时间设置下发与回复
This commit is contained in:
parent
3cf82dba47
commit
a5cd226d97
@ -88,6 +88,11 @@
|
|||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>5.7.5</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
package com.xhpc.pp.logic;
|
package com.xhpc.pp.logic;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.xhpc.common.data.up.PileConfigReplyData;
|
import com.xhpc.common.data.up.PileTimeConfigReplyData;
|
||||||
import com.xhpc.pp.tx.ServiceParameter;
|
import com.xhpc.pp.tx.ServiceParameter;
|
||||||
import com.xhpc.pp.tx.ServiceResult;
|
import com.xhpc.pp.tx.ServiceResult;
|
||||||
import com.xhpc.pp.tx.logic.ServiceLogic;
|
import com.xhpc.pp.tx.logic.ServiceLogic;
|
||||||
@ -12,6 +13,11 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static cn.hutool.core.date.DatePattern.UTC_FORMAT;
|
||||||
|
import static com.xhpc.pp.server.ChargingPileServer.REDIS;
|
||||||
|
import static com.xhpc.pp.utils.security.CP56Time2a.toDate;
|
||||||
|
import static com.xhpc.pp.utils.security.HexUtils.toBytes;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component("PileTimeConfigReplyDataLogic")
|
@Component("PileTimeConfigReplyDataLogic")
|
||||||
public class PileTimeConfigReplyDataLogic implements ServiceLogic {
|
public class PileTimeConfigReplyDataLogic implements ServiceLogic {
|
||||||
@ -23,8 +29,18 @@ public class PileTimeConfigReplyDataLogic implements ServiceLogic {
|
|||||||
|
|
||||||
Map<String, Object> req = sp.getParameters();
|
Map<String, Object> req = sp.getParameters();
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
PileConfigReplyData pileConfigReplyData = objectMapper.convertValue(req, PileConfigReplyData.class);
|
PileTimeConfigReplyData pileTimeConfigReplyData = objectMapper.convertValue(req, PileTimeConfigReplyData.class);
|
||||||
//todo
|
String pileNo = (String) req.get("pileNo");
|
||||||
|
String pk = "pile:".concat(pileNo);
|
||||||
|
Map<String, Object> cachePile = REDIS.getCacheMap(pk);
|
||||||
|
String setTime = (String) cachePile.get("setTime");
|
||||||
|
String configTime = pileTimeConfigReplyData.getSetTime();
|
||||||
|
if (configTime.equals(setTime)) {
|
||||||
|
log.info("({}) set time success", pileNo);
|
||||||
|
} else {
|
||||||
|
// todo may call back mgmt backend
|
||||||
|
log.error("({}) set time failed: √[{}] ×[{}]", pileNo, DateUtil.format(toDate(toBytes(setTime)), UTC_FORMAT), DateUtil.format(toDate(toBytes(configTime)), UTC_FORMAT));
|
||||||
|
}
|
||||||
return new ServiceResult(false);
|
return new ServiceResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,8 +23,9 @@ import java.util.*;
|
|||||||
import static com.xhpc.common.data.redis.SeqUtil.seqHex;
|
import static com.xhpc.common.data.redis.SeqUtil.seqHex;
|
||||||
import static com.xhpc.pp.server.ChargingPileServer.REDIS;
|
import static com.xhpc.pp.server.ChargingPileServer.REDIS;
|
||||||
import static com.xhpc.pp.tx.ServiceResult.OK;
|
import static com.xhpc.pp.tx.ServiceResult.OK;
|
||||||
import static com.xhpc.pp.utils.security.CP56Time2aEncoder.getCP56time2aHex;
|
import static com.xhpc.pp.utils.security.CP56Time2a.toBytes;
|
||||||
import static com.xhpc.pp.utils.security.CRCCalculator.calcCrc;
|
import static com.xhpc.pp.utils.security.CRCCalculator.calcCrc;
|
||||||
|
import static com.xhpc.pp.utils.security.HexUtils.toHex;
|
||||||
|
|
||||||
public class ChargingPileBinaryHandler implements ClientBinaryHandler {
|
public class ChargingPileBinaryHandler implements ClientBinaryHandler {
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ public class ChargingPileBinaryHandler implements ClientBinaryHandler {
|
|||||||
try {
|
try {
|
||||||
List<byte[]> dataList = parseDataList(data);
|
List<byte[]> dataList = parseDataList(data);
|
||||||
for (byte[] d : dataList) {
|
for (byte[] d : dataList) {
|
||||||
String dataStr = HexUtils.toHex(d);
|
String dataStr = toHex(d);
|
||||||
String pileNo = ChargingPileServer.getPileNo(handler);
|
String pileNo = ChargingPileServer.getPileNo(handler);
|
||||||
log.info("received data <<<< |{}| from pile <- ({})", dataStr, pileNo);
|
log.info("received data <<<< |{}| from pile <- ({})", dataStr, pileNo);
|
||||||
if (d.length <= 2 || !dataStr.startsWith("68")) {
|
if (d.length <= 2 || !dataStr.startsWith("68")) {
|
||||||
@ -79,7 +80,7 @@ public class ChargingPileBinaryHandler implements ClientBinaryHandler {
|
|||||||
|
|
||||||
private void process(ClientHandler handler, byte[] data) throws TxException, IOException, NacosException {
|
private void process(ClientHandler handler, byte[] data) throws TxException, IOException, NacosException {
|
||||||
|
|
||||||
String serviceName = HexUtils.toHex(data, 5, 6);
|
String serviceName = toHex(data, 5, 6);
|
||||||
String version = ChargingPileServer.getVersion(handler.getName());
|
String version = ChargingPileServer.getVersion(handler.getName());
|
||||||
Map<String, Object> req = analysis(data, serviceName, version);
|
Map<String, Object> req = analysis(data, serviceName, version);
|
||||||
int seq = HexUtils.toInteger(data, 2, 4);
|
int seq = HexUtils.toInteger(data, 2, 4);
|
||||||
@ -91,14 +92,18 @@ public class ChargingPileBinaryHandler implements ClientBinaryHandler {
|
|||||||
String pilekey = "pile:".concat(pileNo);
|
String pilekey = "pile:".concat(pileNo);
|
||||||
if (SERVICE_REGISTER.equals(serviceName) && OK.equals(resultCode)) {
|
if (SERVICE_REGISTER.equals(serviceName) && OK.equals(resultCode)) {
|
||||||
regHandler(handler, pileNo, req);
|
regHandler(handler, pileNo, req);
|
||||||
String timebin = getTimeBin(seqHex(pilekey.concat("seqhex")), pileNo);
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
String timebin = getTimeBin(seqHex(pilekey.concat("seqhex")), pileNo, calendar);
|
||||||
|
Map<String, Object> cachePile = REDIS.getCacheMap(pilekey);
|
||||||
|
cachePile.put("setTime", toHex(toBytes(calendar.getTime())));
|
||||||
|
REDIS.setCacheMap(pilekey, cachePile);
|
||||||
log.info("server send time config msg >>>> ({}) |{}|", pileNo, timebin);
|
log.info("server send time config msg >>>> ({}) |{}|", pileNo, timebin);
|
||||||
handler.sendClientBinary(HexUtils.toBytes(timebin));
|
handler.sendClientBinary(HexUtils.toBytes(timebin));
|
||||||
} else if (SERVICE_RMCR.equals(serviceName) && OK.equals(resultCode)) {
|
} else if (SERVICE_RMCR.equals(serviceName) && OK.equals(resultCode)) {
|
||||||
setCachePileRM(pilekey);
|
setCachePileRM(pilekey);
|
||||||
}
|
}
|
||||||
if (result.getBinary() != null) {
|
if (result.getBinary() != null) {
|
||||||
log.info("server send msg >>>> ({}) |{}|", pileNo, HexUtils.toHex(result.getBinary()));
|
log.info("server send msg >>>> ({}) |{}|", pileNo, toHex(result.getBinary()));
|
||||||
handler.sendClientBinary(result.getBinary());
|
handler.sendClientBinary(result.getBinary());
|
||||||
if (SERVICE_RMR.equals(serviceName) && OK.equals(resultCode)) {
|
if (SERVICE_RMR.equals(serviceName) && OK.equals(resultCode)) {
|
||||||
setCachePileRM(pilekey);
|
setCachePileRM(pilekey);
|
||||||
@ -106,9 +111,9 @@ public class ChargingPileBinaryHandler implements ClientBinaryHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getTimeBin(String seqhex, String pileNo) {
|
private String getTimeBin(String seqhex, String pileNo, Calendar calendar) {
|
||||||
|
|
||||||
String timebin = "6812".concat(seqhex).concat("0056").concat(pileNo).concat(getCP56time2aHex(Calendar.getInstance()));
|
String timebin = "6812".concat(seqhex).concat("0056").concat(pileNo).concat(toHex(toBytes(calendar.getTime())));
|
||||||
timebin = timebin.concat(CRCCalculator.calcCrc(timebin));
|
timebin = timebin.concat(CRCCalculator.calcCrc(timebin));
|
||||||
return timebin;
|
return timebin;
|
||||||
}
|
}
|
||||||
@ -170,11 +175,11 @@ public class ChargingPileBinaryHandler implements ClientBinaryHandler {
|
|||||||
result.put(field.getCode(), HexUtils.byte2Long(ArrayUtils.subarray(data, pos, pos + field.getLen())));
|
result.put(field.getCode(), HexUtils.byte2Long(ArrayUtils.subarray(data, pos, pos + field.getLen())));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result.put(field.getCode(), HexUtils.toHex(data, pos, pos + field.getLen()));
|
result.put(field.getCode(), toHex(data, pos, pos + field.getLen()));
|
||||||
}
|
}
|
||||||
pos += field.getLen();
|
pos += field.getLen();
|
||||||
}
|
}
|
||||||
result.put("hex", HexUtils.toHex(data));
|
result.put("hex", toHex(data));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,63 @@
|
|||||||
|
package com.xhpc.pp.utils.security;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CP56time2a
|
||||||
|
*
|
||||||
|
* @author drebander
|
||||||
|
* @since 2020-09-11 11:35 上午
|
||||||
|
**/
|
||||||
|
public class CP56Time2a {
|
||||||
|
|
||||||
|
public static Date toDate(byte[] bytes) {
|
||||||
|
|
||||||
|
int milliseconds1 = bytes[0] < 0 ? 256 + bytes[0] : bytes[0];
|
||||||
|
int milliseconds2 = bytes[1] < 0 ? 256 + bytes[1] : bytes[1];
|
||||||
|
int milliseconds = milliseconds1 + milliseconds2 * 256;
|
||||||
|
// 位于 0011 1111
|
||||||
|
int minutes = bytes[2] & 0x3f;
|
||||||
|
// 位于 0001 1111
|
||||||
|
int hours = bytes[3] & 0x1f;
|
||||||
|
// 位于 0000 1111
|
||||||
|
int days = bytes[4] & 0x3f;
|
||||||
|
// 位于 0001 1111
|
||||||
|
int months = bytes[5] & 0x0f;
|
||||||
|
// 位于 0111 1111
|
||||||
|
int years = bytes[6] & 0x7f;
|
||||||
|
Calendar aTime = Calendar.getInstance();
|
||||||
|
aTime.set(Calendar.MILLISECOND, milliseconds);
|
||||||
|
aTime.set(Calendar.MINUTE, minutes);
|
||||||
|
aTime.set(Calendar.HOUR_OF_DAY, hours + 8);
|
||||||
|
aTime.set(Calendar.DAY_OF_MONTH, days);
|
||||||
|
aTime.set(Calendar.MONTH, months - 1);
|
||||||
|
aTime.set(Calendar.YEAR, years + 2000);
|
||||||
|
return aTime.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] toBytes(Date aDate) {
|
||||||
|
|
||||||
|
byte[] result = new byte[7];
|
||||||
|
Calendar aTime = Calendar.getInstance();
|
||||||
|
aTime.setTime(aDate);
|
||||||
|
final int milliseconds = aTime.get(Calendar.MILLISECOND);
|
||||||
|
result[0] = (byte) (milliseconds % 256);
|
||||||
|
result[1] = (byte) (milliseconds / 256);
|
||||||
|
result[2] = (byte) aTime.get(Calendar.MINUTE);
|
||||||
|
result[3] = (byte) aTime.get(Calendar.HOUR_OF_DAY);
|
||||||
|
result[4] = (byte) aTime.get(Calendar.DAY_OF_MONTH);
|
||||||
|
result[5] = (byte) aTime.get(Calendar.MONTH);
|
||||||
|
result[6] = (byte) (aTime.get(Calendar.YEAR) % 100);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public static void main(String[] args) {
|
||||||
|
// Date aDate = new Date();
|
||||||
|
// System.out.println(aDate);
|
||||||
|
// final byte[] bytes = toBytes(aDate);
|
||||||
|
// final Date date = toDate(bytes);
|
||||||
|
// System.out.println(date);
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,62 +0,0 @@
|
|||||||
package com.xhpc.pp.utils.security;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
public class CP56Time2aEncoder {
|
|
||||||
|
|
||||||
private byte octetset[];
|
|
||||||
private Object dataset[];
|
|
||||||
|
|
||||||
public CP56Time2aEncoder(Calendar calendar) {
|
|
||||||
|
|
||||||
int k;
|
|
||||||
int i = 7;
|
|
||||||
octetset = new byte[i];
|
|
||||||
int j = 13;
|
|
||||||
dataset = new Object[j];
|
|
||||||
for (k = 0; k < i; k++) {
|
|
||||||
octetset[k] = (byte) 0x00;
|
|
||||||
}
|
|
||||||
for (k = 0; k < j; k++) {
|
|
||||||
dataset[k] = null;
|
|
||||||
}
|
|
||||||
dataset[0] = calendar.get(Calendar.MILLISECOND) + 1000 * calendar.get(Calendar.SECOND);
|
|
||||||
dataset[1] = (byte) calendar.get(Calendar.MINUTE);
|
|
||||||
dataset[2] = Boolean.FALSE;
|
|
||||||
dataset[3] = Boolean.FALSE;
|
|
||||||
dataset[4] = (byte) calendar.get(Calendar.HOUR_OF_DAY);
|
|
||||||
dataset[5] = Boolean.FALSE;
|
|
||||||
dataset[6] = Boolean.TRUE; //summertime
|
|
||||||
dataset[7] = (byte) calendar.get(Calendar.DAY_OF_MONTH);
|
|
||||||
dataset[8] = (byte) calendar.get(Calendar.DAY_OF_WEEK);
|
|
||||||
dataset[9] = (byte) (calendar.get(Calendar.MONTH) + 1);
|
|
||||||
dataset[10] = (byte) 0x00;
|
|
||||||
|
|
||||||
int year = calendar.get(Calendar.YEAR);
|
|
||||||
|
|
||||||
year = Math.round((float) Math.IEEEremainder(year, 100));
|
|
||||||
|
|
||||||
dataset[11] = (byte) (year);
|
|
||||||
dataset[12] = Boolean.FALSE;
|
|
||||||
code();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void code() {
|
|
||||||
|
|
||||||
octetset[0] = (byte) ((Integer) dataset[0] & 0xFF); //Millisecond
|
|
||||||
octetset[1] = (byte) (((Integer) dataset[0] & 0xFF00) >> 8); //Millisecond
|
|
||||||
octetset[2] = ((Byte) dataset[1]); // Minutes
|
|
||||||
octetset[3] = (byte) ((Byte) dataset[4] | ((((Boolean) dataset[6]) ? 1 : 0) << 7)); //summertime
|
|
||||||
octetset[4] = (byte) (((Byte) dataset[7]) | ((Byte) dataset[8] << 5)); // weekday day of month
|
|
||||||
octetset[5] = (byte) ((Byte) dataset[9] | ((Byte) dataset[10] << 4)); // month
|
|
||||||
octetset[6] = (byte) dataset[11]; // year
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getCP56time2aHex(Calendar calendar) {
|
|
||||||
|
|
||||||
CP56Time2aEncoder encoder = new CP56Time2aEncoder(calendar);
|
|
||||||
encoder.code();
|
|
||||||
return HexUtils.toHex(encoder.octetset);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,10 +1,14 @@
|
|||||||
package com.xhpc.pp.utils.security;
|
package com.xhpc.pp.utils.security;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
import static cn.hutool.core.date.DatePattern.UTC_FORMAT;
|
||||||
import static com.xhpc.common.core.utils.StringUtils.capitalize;
|
import static com.xhpc.common.core.utils.StringUtils.capitalize;
|
||||||
import static com.xhpc.pp.utils.security.Cp56Time2aDecoder.getCP56time2a;
|
import static com.xhpc.pp.utils.security.CP56Time2a.toDate;
|
||||||
|
import static com.xhpc.pp.utils.security.HexUtils.toBytes;
|
||||||
|
|
||||||
public class CacheDataUtils {
|
public class CacheDataUtils {
|
||||||
|
|
||||||
@ -18,7 +22,7 @@ public class CacheDataUtils {
|
|||||||
if (tarfield.getType().getSimpleName().equals("Integer")) {
|
if (tarfield.getType().getSimpleName().equals("Integer")) {
|
||||||
tarval = HexUtils.reverseHexInt(srcval);
|
tarval = HexUtils.reverseHexInt(srcval);
|
||||||
} else if (tarFieldName.contains("ime")) {
|
} else if (tarFieldName.contains("ime")) {
|
||||||
tarval = getCP56time2a(srcval);
|
tarval = DateUtil.format(toDate(toBytes(srcval)), UTC_FORMAT);
|
||||||
} else {
|
} else {
|
||||||
tarval = srcval;
|
tarval = srcval;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
package com.xhpc.pp.utils.security;
|
|
||||||
|
|
||||||
public class Cp56Time2aDecoder {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
|
|
||||||
String date = getCP56time2a("F0D2210F060815");
|
|
||||||
System.out.println(date);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getCP56time2a(String str) {
|
|
||||||
|
|
||||||
return "20" + Integer.parseInt(str.substring(12, 14), 16) + "-" + Integer.parseInt(str.substring(10, 12), 16)
|
|
||||||
+ "-" + Integer.parseInt(str.substring(8, 10), 16) + "T" + Integer.parseInt(str.substring(6, 8), 16)
|
|
||||||
+ ":" + Integer.parseInt(str.substring(4, 6), 16) + ":"
|
|
||||||
+ Integer.parseInt(str.substring(2, 4) + "" + str.substring(0, 2), 16) / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user