屏蔽nacos日志;日期编码;时间下发;启停回调;90秒响应超时;桩SOC

This commit is contained in:
ZZ 2021-08-16 15:20:06 +08:00
parent 2117bd2b99
commit 98aa23e042
15 changed files with 196 additions and 47 deletions

View File

@ -27,12 +27,13 @@ public interface PileOrderService {
/**
* 桩停止回调接口
* @param orderNo 订单号
* @param status 1 成功 2失败
* @param remark 备注
*
* @param orderNo 订单号
* @param status 1 成功 2失败
* @param remark 备注
* @return
*/
@GetMapping("/chargeOrder/pileStopup")
R pileStopup(@RequestParam("orderNo") String orderNo,@RequestParam("status") Integer status,@RequestParam("remark") String remark);
@GetMapping("/chargeOrder/pileStop")
R pileStop(@RequestParam("orderNo") String orderNo, @RequestParam("status") Integer status, @RequestParam("remark") String remark);
}

View File

@ -28,7 +28,7 @@ public class PileOrderFallbackFactory implements FallbackFactory<PileOrderServic
}
@Override
public R pileStopup(String orderNo, Integer status, String remark) {
public R pileStop(String orderNo, Integer status, String remark) {
return R.fail("桩停止回调接口失败:" + cause.getMessage());
}

View File

@ -20,7 +20,7 @@ public class StartChargingData {
public String getOrderNo() {
return orderNo;
return String.format("%032d", Long.parseLong(orderNo));
}
public void setOrderNo(String orderNo) {

View File

@ -46,7 +46,7 @@ public class HxpcPileOrderController extends BaseController {
*/
@GetMapping("/test/chargeOrder/pileStartup")
private R test(@RequestParam String orderNo, @RequestParam Integer status, @RequestParam String remark){
R r = pileOrderService.pileStopup(orderNo, status, remark);
R r = pileOrderService.pileStop(orderNo, status, remark);
return r;
}
@ -84,23 +84,24 @@ public class HxpcPileOrderController extends BaseController {
/**
* 桩停止回调接口
* @param orderNo 订单号
* @param status 1 成功 2失败
* @param remark 备注
*
* @param orderNo 订单号
* @param status 1 成功 2失败
* @param remark 备注
* @return
*/
@GetMapping("/chargeOrder/pileStopup")
public R pileStopup(String orderNo,Integer status,String remark){
@GetMapping("/chargeOrder/pileStop")
public R pileStop(String orderNo, Integer status, String remark) {
//解析订单编号
String s = orderNo.split("\\.")[0];
String s1 = s.split(":")[1];
Integer code=300 ;
Long userId=update(status, 0,remark, s1,1);
Map<String,Object> map =new HashMap<>();
map.put("code",code);
map.put("userId",userId);
if(status==1){
map.put("message","停止充电成功");
Integer code = 300;
Long userId = update(status, 0, remark, s1, 1);
Map<String, Object> map = new HashMap<>();
map.put("code", code);
map.put("userId", userId);
if (status == 1) {
map.put("message", "停止充电成功");
}else{
map.put("message",remark);
}

View File

@ -22,6 +22,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.Calendar;
import java.util.Map;
import static com.xhpc.common.data.redis.SeqUtil.seqHex;
@ -200,6 +201,11 @@ public class ChargingController {
if (clientHandler == null) return R.fail("充电桩没有连接到上次注册的服务器");
try {
String gunkey = "gun:".concat(pileNo).concat(startChargingData.getGunId());
Map<String, Object> cacheGun = REDIS.getCacheMap(gunkey);
Long orderstarttime = (Long) cacheGun.get("orderstarttime");
if (orderstarttime != null) {
return R.fail("等待上一条指令响应");
}
String skey = gunkey.concat(".seqhex");
String seq = seqHex(skey);
byte[] msg = translateStart(startChargingData, seq);
@ -210,14 +216,10 @@ public class ChargingController {
cacheOrder.put("balance", balance);
cacheOrder.put("tel", startChargingData.getTel());
REDIS.setCacheMap(orderkey, cacheOrder);
Map<String, Object> cacheGun = REDIS.getCacheMap(gunkey);
String orderkeyOld = (String) cacheGun.get("orderkey");
if (orderkeyOld != null) { // todo 测试代码,生产发布时删除
REDIS.deleteObject(orderkeyOld);
}
cacheGun.put("orderstarttime", Calendar.getInstance().getTimeInMillis());
cacheGun.put("orderkey", orderkey);
REDIS.setCacheMap(gunkey, cacheOrder);
return R.ok("订单启动指令已下发至充电桩");
REDIS.setCacheMap(gunkey, cacheGun);
return R.ok("指令已下发至充电桩");
} catch (IOException e) {
log.error("send message failed. " + e.getMessage(), e);
return R.fail(e.getMessage());
@ -231,11 +233,18 @@ public class ChargingController {
if (clientHandler == null) return R.fail("充电桩没有连接到上次注册的服务器");
try {
String gunkey = "gun:".concat(pileNo).concat(gunId);
Map<String, Object> cacheGun = REDIS.getCacheMap(gunkey);
Long orderstoptime = (Long) cacheGun.get("orderstoptime");
if (orderstoptime != null) {
return R.fail("等待上一条指令响应");
}
String skey = gunkey.concat(".seqhex");
String seq = seqHex(skey);
byte[] msg = translateStop(pileNo, gunId, version, seq);
clientHandler.sendClientBinary(msg);
return R.ok();
cacheGun.put("orderstoptime", Calendar.getInstance().getTimeInMillis());
REDIS.setCacheMap(gunkey, cacheGun);
return R.ok("指令已下发至充电桩");
} catch (IOException e) {
log.error("send message failed. " + e.getMessage(), e);
return R.fail(e.getMessage());

View File

@ -1,6 +1,7 @@
package com.xhpc.pp.logic;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xhpc.common.api.PileOrderService;
import com.xhpc.common.data.redis.CacheRealtimeData;
import com.xhpc.common.data.up.RealtimeData;
import com.xhpc.pp.tx.ServiceParameter;
@ -8,6 +9,7 @@ import com.xhpc.pp.tx.ServiceResult;
import com.xhpc.pp.tx.logic.ServiceLogic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@ -20,6 +22,7 @@ import java.util.Map;
import static com.xhpc.pp.server.ChargingPileServer.REDIS;
import static com.xhpc.pp.utils.security.CacheDataUtils.reflectTranslate;
import static com.xhpc.pp.utils.security.HexUtils.reverseHexInt;
import static com.xhpc.pp.utils.security.HexUtils.toBits;
@Lazy
@ -28,9 +31,12 @@ public class RealtimeDataLogic implements ServiceLogic {
private static Logger log = LoggerFactory.getLogger(RealtimeDataLogic.class);
public static final String[] stable = {"离线","故障","空闲","充电"};
public static final String[] stable = {"离线", "故障", "空闲", "充电"};
public static final String[] pvgstable = {"", "", "未知"};
private static final String[] hftable = {"急停按钮动作故障","无可用整流模块","出风口温度过高","交流防雷故障","交直流模块DC20通信中断","绝缘检测模块FC08通信中断","电度表通信中断","读卡器通信中断","RC10通信中断","风扇调速板故障","直流熔断器故障","高压接触器故障","门打开"};
private static final String[] hftable = {"急停按钮动作故障", "无可用整流模块", "出风口温度过高", "交流防雷故障", "交直流模块DC20通信中断", "绝缘检测模块FC08通信中断", "电度表通信中断", "读卡器通信中断", "RC10通信中断", "风扇调速板故障", "直流熔断器故障", "高压接触器故障", "门打开"};
@Autowired
private PileOrderService pileOrderService;
@Override
public ServiceResult service(ServiceParameter sp) throws Exception {
@ -40,37 +46,55 @@ public class RealtimeDataLogic implements ServiceLogic {
RealtimeData realtimeData = objectMapper.convertValue(req, RealtimeData.class);
String pileNo = realtimeData.getPileNo();
String gunId = realtimeData.getGunId();
String terminalId = pileNo.concat(gunId);
String gunkey = "gun:".concat(terminalId);
realtimeData.setCreateBy("SYSTEM");
realtimeData.setCreateTime(Calendar.getInstance().getTime());
String gunkey = "gun:".concat(pileNo).concat(gunId);
Map<String, Object> cacheGun = REDIS.getCacheMap(gunkey);
String statusplain = stable[Integer.parseInt(realtimeData.getStatus())];
cacheGun.put("status", statusplain);
cacheGun.put("pileGunStatus", pvgstable[Integer.parseInt(realtimeData.getPileGunStatus())]);
cacheGun.put("vehicleGunStatus", pvgstable[Integer.parseInt(realtimeData.getVehicleGunStatus())]);
String hardwareFault = realtimeData.getHardwareFault();
String hfs = toBits(hardwareFault);
char[] hfcs = hfs.toCharArray();
String hfsplain = "";
for (int i = hfcs.length-1; i >=0; i--) {
for (int i = hfcs.length - 1; i >= 0; i--) {
if (hfcs[i] == 49) {
hfsplain = hfsplain.concat(hftable[hfcs.length-i-1]).concat("");
hfsplain = hfsplain.concat(hftable[hfcs.length - i - 1]).concat("");
}
}
cacheGun.put("hf", hfsplain);
REDIS.setCacheMap(gunkey, cacheGun);
String orderNo = realtimeData.getOrderNo();
String orderkey = "order:".concat(orderNo);
String soc = realtimeData.getSoc();
String pkey = "pile:".concat(pileNo);
Map<String, Object> cachePile = REDIS.getCacheMap(pkey);
String stationTermStatusKey = "stationTerminalStatus:".concat(cachePile.get("stationId").toString());
String statusOrSOC;
Integer socInt = Integer.valueOf(soc);
if (statusplain.equals("充电")) {
statusOrSOC = socInt.toString();
} else {
statusOrSOC = statusplain;
}
Integer tr = reverseHexInt(realtimeData.getRemainingTime());
cacheGun.put("status", statusOrSOC);
cacheGun.put("remainingTime", tr);
REDIS.setCacheMap(gunkey, cacheGun);
Map<String, Object> cacheTerminalStatusMap = REDIS.getCacheMap(stationTermStatusKey);
cacheTerminalStatusMap.put(terminalId, statusOrSOC);
REDIS.setCacheMap(stationTermStatusKey, cacheTerminalStatusMap);
Map<String, Object> cacheOrder = REDIS.getCacheMap(orderkey);
List<CacheRealtimeData> realtimeDataList = (List<CacheRealtimeData>) cacheOrder.get("realtimeDataList");
if (!orderNo.equals("00000000000000000000000000000000")) {
Map<String, Object> cacheOrder = REDIS.getCacheMap(orderkey);
List<CacheRealtimeData> realtimeDataList = (List<CacheRealtimeData>) cacheOrder.get("realtimeDataList");
if (realtimeDataList == null) {
realtimeDataList = new ArrayList<>();
}
Integer balance = (Integer) cacheOrder.get("balance");
CacheRealtimeData cacheRealtimeData = translate(realtimeData);
realtimeDataList.add(cacheRealtimeData);
cacheOrder.put("soc", realtimeData.getSoc());
cacheOrder.put("soc", socInt);
cacheOrder.put("remainingTime", tr);
cacheOrder.put("status", statusplain);
cacheOrder.put("realtimeDataList", realtimeDataList);
REDIS.setCacheMap(orderkey, cacheOrder);
@ -82,6 +106,20 @@ public class RealtimeDataLogic implements ServiceLogic {
cacheOrder.put("alerted", "true");
}
}
} else {
Long orderstarttime = (Long) cacheGun.get("orderstarttime");
Long orderstoptime = (Long) cacheGun.get("orderstoptime");
orderkey = (String) cacheGun.get("orderkey");
if (orderstarttime != null && orderkey != null && realtimeDataList == null && Calendar.getInstance().getTimeInMillis() - orderstarttime > 90 * 1000) {
pileOrderService.pileStartup(orderNo, 2, "终端90秒内没有响应");
cacheGun.remove("orderkey");
cacheGun.remove("orderstarttime");
REDIS.setCacheMap(gunkey, cacheGun);
} else if (orderstoptime != null && orderkey != null && Calendar.getInstance().getTimeInMillis() - orderstoptime > 90 * 1000) {
pileOrderService.pileStop(orderNo, 2, "终端90秒内没有响应");
cacheGun.remove("orderstoptime");
REDIS.setCacheMap(gunkey, cacheGun);
}
}
return new ServiceResult(false);
}

View File

@ -1,12 +1,14 @@
package com.xhpc.pp.logic;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xhpc.common.api.PileOrderService;
import com.xhpc.common.data.up.RemoteStartReplyData;
import com.xhpc.pp.tx.ServiceParameter;
import com.xhpc.pp.tx.ServiceResult;
import com.xhpc.pp.tx.logic.ServiceLogic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@ -20,6 +22,9 @@ public class RemoteStartReplyDataLogic implements ServiceLogic {
private static Logger log = LoggerFactory.getLogger(RemoteStartReplyDataLogic.class);
@Autowired
private PileOrderService pileOrderService;
@Override
public ServiceResult service(ServiceParameter sp) throws Exception {
@ -32,6 +37,14 @@ public class RemoteStartReplyDataLogic implements ServiceLogic {
String startResult = remoteStartReplyData.getStartResult();
cacheOrder.put("startResult", startResult);
REDIS.setCacheMap(orderkey, cacheOrder);
String gunkey = "gun:".concat(remoteStartReplyData.getPileNo()).concat(remoteStartReplyData.getGunId());
Map<String, Object> cacheGun = REDIS.getCacheMap(gunkey);
Long orderstarttime = (Long) cacheGun.get("orderstarttime");
if (orderstarttime != null) {
pileOrderService.pileStartup(orderNo, 1, "启动充电成功");
cacheGun.remove("orderstarttime");
REDIS.setCacheMap(gunkey, cacheGun);
}
return new ServiceResult(false);
}

View File

@ -1,12 +1,14 @@
package com.xhpc.pp.logic;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xhpc.common.api.PileOrderService;
import com.xhpc.common.data.up.RemoteStopReplyData;
import com.xhpc.pp.tx.ServiceParameter;
import com.xhpc.pp.tx.ServiceResult;
import com.xhpc.pp.tx.logic.ServiceLogic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@ -20,6 +22,9 @@ public class RemoteStopReplyDataLogic implements ServiceLogic {
private static Logger log = LoggerFactory.getLogger(RemoteStopReplyDataLogic.class);
@Autowired
private PileOrderService pileOrderService;
@Override
public ServiceResult service(ServiceParameter sp) throws Exception {
@ -33,6 +38,12 @@ public class RemoteStopReplyDataLogic implements ServiceLogic {
String stopResult = remoteStopReplyData.getStopResult();
cacheOrder.put("stopResult", stopResult);
REDIS.setCacheMap(orderkey, cacheOrder);
Long orderstoptime = (Long) cacheGun.get("orderstoptime");
if (orderstoptime != null) {
pileOrderService.pileStop(orderkey.replace("order:", ""), 1, "停止充电成功");
cacheGun.remove("orderstoptime");
REDIS.setCacheMap(gunkey, cacheGun);
}
return new ServiceResult(false);
}

View File

@ -9,6 +9,7 @@ import com.xhpc.pp.tx.ServiceParameter;
import com.xhpc.pp.tx.ServiceResult;
import com.xhpc.pp.tx.TxException;
import com.xhpc.pp.utils.SpringContextHolder;
import com.xhpc.pp.utils.security.CRCCalculator;
import com.xhpc.pp.utils.security.HexUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.quickserver.net.server.ClientBinaryHandler;
@ -17,13 +18,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import static com.xhpc.common.data.redis.SeqUtil.seqHex;
import static com.xhpc.pp.server.ChargingPileServer.REDIS;
import static com.xhpc.pp.tx.ServiceResult.OK;
import static com.xhpc.pp.utils.security.CP56Time2aEncoder.getCP56time2aHex;
import static com.xhpc.pp.utils.security.CRCCalculator.calcCrc;
public class ChargingPileBinaryHandler implements ClientBinaryHandler {
@ -91,6 +91,9 @@ public class ChargingPileBinaryHandler implements ClientBinaryHandler {
String pilekey = "pile:".concat(pileNo);
if (SERVICE_REGISTER.equals(serviceName) && OK.equals(resultCode)) {
regHandler(handler, pileNo, req);
String timebin = getTimeBin(seqHex(pilekey.concat("seqhex")), pileNo);
log.info("server send time config msg >>>> ({}) |{}|", pileNo, timebin);
handler.sendClientBinary(HexUtils.toBytes(timebin));
} else if (SERVICE_RMCR.equals(serviceName) && OK.equals(resultCode)) {
setCachePileRM(pilekey);
}
@ -103,6 +106,13 @@ public class ChargingPileBinaryHandler implements ClientBinaryHandler {
}
}
private String getTimeBin(String seqhex, String pileNo) {
String timebin = "6812".concat(seqhex).concat("0056").concat(pileNo).concat(getCP56time2aHex(Calendar.getInstance()));
timebin = timebin.concat(CRCCalculator.calcCrc(timebin));
return timebin;
}
private void regHandler(ClientHandler handler, String pileNo, Map<String, Object> req) {
ChargingPileServer.putHandler(pileNo, handler);

View File

@ -77,7 +77,7 @@ public class ChargingPileServer {
config.getServerMode().setBlocking(true);
config.setPort(port);
config.setBindAddr(host);
config.setTimeout(60 * 1000 * 5);
config.setTimeout(66 * 1000 * 5);
server.initService(config);
server.startServer();
log.info("pp svc started at {}:{} ....", host, port);

View File

@ -0,0 +1,62 @@
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);
}
}

View File

@ -4,7 +4,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import static com.xhpc.common.core.utils.StringUtils.capitalize;
import static com.xhpc.pp.utils.security.Cp56Time2a.getCP56time2a;
import static com.xhpc.pp.utils.security.Cp56Time2aDecoder.getCP56time2a;
public class CacheDataUtils {

View File

@ -1,6 +1,6 @@
package com.xhpc.pp.utils.security;
public class Cp56Time2a {
public class Cp56Time2aDecoder {
public static void main(String[] args) {
@ -17,3 +17,4 @@ public class Cp56Time2a {
}
}

View File

@ -180,10 +180,11 @@ public class HexUtils {
public static void main(String[] args) {
System.out.println(Integer.parseInt("FFFF", 16));
System.out.println(Integer.parseInt("FF00", 16));
System.out.println(reverseHexInt("FF00"));
byte[] data1 = toBytes(reverseHex("FC080000"));
System.out.println(toInteger(data1, 0, 4));
// System.out.println(reverseHexInt("A0860100"));
System.out.println(reverseHexInt("FC080000"));
// System.out.println(toHexInt(100000));
System.out.println(toBits("1000"));
}

View File

@ -61,6 +61,8 @@
<logger name="com.xhpc" level="info"/>
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn"/>
<!-- nacos -->
<logger name="com.alibaba.nacos" level="warn"/>
<root level="info">
<appender-ref ref="console"/>