日期格式;单字节整数解析;启动/中止充电响应回调;上一条指令下发时间间隔500ms;

This commit is contained in:
ZZ 2021-08-18 15:41:38 +08:00
parent f2e711390c
commit bf12d65d9a
11 changed files with 85 additions and 58 deletions

View File

@ -2,7 +2,7 @@ package com.xhpc.common.data.redis;
import com.xhpc.common.data.up.BaseData;
//充电订单实时数据
//充电订单结算数据
public class CacheOrderData extends BaseData {
private String orderNo; //交易流水号

View File

@ -2,6 +2,7 @@ package com.xhpc.common.data.redis;
import com.xhpc.common.data.up.BaseData;
//订单实时数据
public class CacheRealtimeData extends BaseData {
private String orderNo; //交易流水号

View File

@ -1,5 +1,6 @@
package com.xhpc.pp.controller;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xhpc.common.api.PowerPileService;
@ -24,7 +25,9 @@ import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.Calendar;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMAT;
import static com.xhpc.common.data.redis.SeqUtil.seqHex;
import static com.xhpc.pp.logic.RegisterLogic.REGISTERED;
import static com.xhpc.pp.server.ChargingPileServer.*;
@ -206,10 +209,11 @@ public class ChargingController {
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 gunstatus = (String) cacheGun.get("status");
if (!"空闲".equals(gunstatus)) {
return R.fail("充电桩不在空闲正常状态,稍后再试");
}
if (hori(gunkey)) return R.fail("等待上一条指令响应");
String skey = gunkey.concat(".seqhex");
String seq = seqHex(skey);
byte[] msg = translateStart(startChargingData, seq);
@ -224,7 +228,8 @@ public class ChargingController {
cacheOrder.put("balance", balance);
cacheOrder.put("tel", startChargingData.getTel());
REDIS.setCacheMap(orderkey, cacheOrder);
cacheGun.put("orderstarttime", Calendar.getInstance().getTimeInMillis());
cacheGun.put("orderstarttime", DateUtil.format(Calendar.getInstance().getTime(), NORM_DATETIME_FORMAT));
cacheGun.put("orderstoptime", null);
cacheGun.put("orderkey", orderkey);
REDIS.setCacheMap(gunkey, cacheGun);
return R.ok("指令已下发至充电桩");
@ -234,6 +239,17 @@ public class ChargingController {
}
}
private boolean hori(String gunkey) {
String hori = gunkey.concat(".hori");
String HORI = REDIS.getCacheObject(hori);
if (HORI != null) {
return true;
}
REDIS.setCacheObject(hori, "protection film", 300L, TimeUnit.MILLISECONDS);
return false;
}
@GetMapping("native/charging/stop/{pileNo}/{gunId}/{version}")
public R nativeStopCharging(@PathVariable("pileNo") String pileNo, @PathVariable("gunId") String gunId, @PathVariable("version") String version) {
@ -242,15 +258,11 @@ public class ChargingController {
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("等待上一条指令响应");
}
if (hori(gunkey)) return R.fail("等待上一条指令响应");
String skey = gunkey.concat(".seqhex");
String seq = seqHex(skey);
byte[] msg = translateStop(pileNo, gunId, version, seq);
clientHandler.sendClientBinary(msg);
cacheGun.put("orderstoptime", Calendar.getInstance().getTimeInMillis());
REDIS.setCacheMap(gunkey, cacheGun);
return R.ok("指令已下发至充电桩");
} catch (IOException e) {

View File

@ -36,10 +36,16 @@ public class OrderDataLogic implements ServiceLogic {
String orderNo = orderData.getOrderNo();
String orderkey = "order:".concat(orderNo);
Map<String, Object> cacheOrder = REDIS.getCacheMap(orderkey);
cacheOrder.put("status", "完成结算");
cacheOrder.put("orderData", translate(orderData));
cacheOrder.put("orderResult", 1);
CacheOrderData cacheOrderData = translate(orderData);
cacheOrder.put("orderData", cacheOrderData);
REDIS.setCacheMap(orderkey, cacheOrder);
String gunkey = "gun:".concat(orderData.getPileNo()).concat(orderData.getGunId());
Map<String, Object> cacheGun = REDIS.getCacheMap(gunkey);
cacheGun.put("orderstarttime", null);
cacheGun.put("orderstoptime", orderData.getEndTime());
cacheGun.put("orderkey", null);
REDIS.setCacheMap(gunkey, cacheGun);
String skey = gunkey.concat(".seqhex");
String seq = seqHex(skey);
String resultStr = "6815".concat(seq).concat("0040").concat(orderNo).concat(ServiceResult.HEX_OK);
@ -47,7 +53,7 @@ public class OrderDataLogic implements ServiceLogic {
return new ServiceResult(HexUtils.toBytes(resultStr), ServiceResult.OK);
}
private CacheOrderData translate(OrderData orderData) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException, InstantiationException {
private CacheOrderData translate(OrderData orderData) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
Class<CacheOrderData> codclz = CacheOrderData.class;
Class<OrderData> odclz = OrderData.class;

View File

@ -13,7 +13,7 @@ import org.springframework.stereotype.Component;
import java.util.Map;
import static cn.hutool.core.date.DatePattern.UTC_SIMPLE_PATTERN;
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMAT;
import static com.xhpc.pp.server.ChargingPileServer.REDIS;
import static com.xhpc.pp.utils.security.CP56Time2a.cp56toDate;
@ -31,7 +31,7 @@ public class PileTimeConfigReplyDataLogic implements ServiceLogic {
PileTimeConfigReplyData pileTimeConfigReplyData = objectMapper.convertValue(req, PileTimeConfigReplyData.class);
String pileNo = (String) req.get("pileNo");
String pk = "pile:".concat(pileNo);
String configTime = DateUtil.format(cp56toDate(pileTimeConfigReplyData.getSetTime()), UTC_SIMPLE_PATTERN);
String configTime = DateUtil.format(cp56toDate(pileTimeConfigReplyData.getSetTime()), NORM_DATETIME_FORMAT);
Map<String, Object> cachePile = REDIS.getCacheMap(pk);
cachePile.put("configTime", configTime);
REDIS.setCacheMap(pk, cachePile);

View File

@ -43,7 +43,6 @@ public class RealtimeDataLogic implements ServiceLogic {
@Autowired
private PileOrderService pileOrderService;
@Override
public ServiceResult service(ServiceParameter sp) throws Exception {
@ -77,7 +76,7 @@ public class RealtimeDataLogic implements ServiceLogic {
Map<String, Object> cachePile = REDIS.getCacheMap(pkey);
String stationTermStatusKey = "stationTerminalStatus:".concat(cachePile.get("stationId").toString());
String statusOrSOC;
Integer socInt = Integer.valueOf(soc);
Integer socInt = Integer.parseInt(soc, 16);
if (statusplain.equals("充电")) {
statusOrSOC = socInt.toString();
} else {
@ -99,35 +98,27 @@ public class RealtimeDataLogic implements ServiceLogic {
Integer balance = (Integer) cacheOrder.get("balance");
CacheRealtimeData cacheRealtimeData = translate(realtimeData);
realtimeDataList.add(cacheRealtimeData);
cacheOrder.put("soc", socInt);
String lord = orderkey.concat(".lord");
REDIS.setCacheObject(lord, cacheRealtimeData);
if (statusplain.equals("充电")) {
Integer startSoc = (Integer) cacheOrder.get("startSoc");
if (startSoc == null) cacheOrder.put("startSoc", socInt);
cacheOrder.put("endSoc", socInt);
}
cacheOrder.put("remainingTime", tr);
cacheOrder.put("status", statusplain);
cacheOrder.put("realtimeDataList", realtimeDataList);
orderkey = (String) cacheGun.get("orderkey");
REDIS.setCacheMap(orderkey, cacheOrder);
if ((balance - cacheRealtimeData.getAmountCharged()) < 500) {
String alerted = (String) cacheOrder.get("lt5alerted");
String tel = (String) cacheOrder.get("tel");
if (alerted == null && tel != null) {
smsService.sendNotice(tel,"【小华充电】尊敬的用户你的账户余额小于5元,为不影响您的正常充电,请您尽快充值交费,谢谢。");
smsService.sendNotice(tel, "【小华充电】尊敬的用户你的账户余额小于5元,为不影响您的正常充电,请您尽快充值交费,谢谢。");
cacheOrder.put("lt5alerted", "true");
REDIS.setCacheMap(orderkey, cacheOrder);
}
}
} else {
Long orderstarttime = (Long) cacheGun.get("orderstarttime");
Long orderstoptime = (Long) cacheGun.get("orderstoptime");
orderkey = (String) cacheGun.get("orderkey");
log.info("--0s order rtd--");
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);
log.info("--rmv ost--");
} 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

@ -15,12 +15,14 @@ import org.springframework.stereotype.Component;
import java.util.Map;
import static com.xhpc.pp.server.ChargingPileServer.REDIS;
import static com.xhpc.pp.tx.ServiceResult.HEX_OK;
@Lazy
@Component("RemoteStartReplyDataLogic")
public class RemoteStartReplyDataLogic implements ServiceLogic {
private static Logger log = LoggerFactory.getLogger(RemoteStartReplyDataLogic.class);
private static String[] frs = {"", "设备编号不匹配", "枪已在充电", "设备故障", "设备离线", "未插枪",};
@Autowired
private PileOrderService pileOrderService;
@ -36,14 +38,16 @@ public class RemoteStartReplyDataLogic implements ServiceLogic {
Map<String, Object> cacheOrder = REDIS.getCacheMap(orderkey);
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);
REDIS.setCacheMap(orderkey, cacheOrder);
if (HEX_OK.equals(remoteStartReplyData.getStartResult())) {
pileOrderService.pileStartup(orderNo, 1, "启动充电成功");
} else {
cacheGun.put("orderkey", null);
REDIS.setCacheMap(gunkey, cacheGun);
pileOrderService.pileStartup(orderNo, 2, frs[Integer.parseInt(remoteStartReplyData.getFailReason())]);
}
return new ServiceResult(false);
}

View File

@ -15,6 +15,7 @@ import org.springframework.stereotype.Component;
import java.util.Map;
import static com.xhpc.pp.server.ChargingPileServer.REDIS;
import static com.xhpc.pp.tx.ServiceResult.HEX_OK;
@Lazy
@Component("RemoteStopReplyDataLogic")
@ -24,6 +25,7 @@ public class RemoteStopReplyDataLogic implements ServiceLogic {
@Autowired
private PileOrderService pileOrderService;
private static String[] frs = {"", "设备编号不匹配", "枪未处于充电状态", "其他"};
@Override
public ServiceResult service(ServiceParameter sp) throws Exception {
@ -38,11 +40,11 @@ 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);
String orderNo = orderkey.replace("order:", "");
if (HEX_OK.equals(remoteStopReplyData.getStopResult())) {
pileOrderService.pileStop(orderNo, 1, "停止充电成功");
} else {
pileOrderService.pileStartup(orderNo, 2, frs[Integer.parseInt(remoteStopReplyData.getFailReason())]);
}
return new ServiceResult(false);
}

View File

@ -2,6 +2,7 @@ package com.xhpc.pp.server;
import cn.hutool.core.date.DateUtil;
import com.alibaba.nacos.api.exception.NacosException;
import com.xhpc.common.api.PileOrderService;
import com.xhpc.common.api.dto.ChargingStationDto;
import com.xhpc.pp.domain.ServiceField;
import com.xhpc.pp.logic.FieldLogic;
@ -17,11 +18,12 @@ import org.quickserver.net.server.ClientBinaryHandler;
import org.quickserver.net.server.ClientHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import java.util.*;
import static cn.hutool.core.date.DatePattern.UTC_SIMPLE_PATTERN;
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMAT;
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;
@ -36,6 +38,7 @@ public class ChargingPileBinaryHandler implements ClientBinaryHandler {
private static final String SERVICE_REGISTER = "01";
private static final String SERVICE_HB = "03";
private static final String SERVICE_RMR = "09";
private static final String SERVICE_OD = "3B";
private static final String SERVICE_RMCR = "57";
private static final String DATA_TYPE_STRING = "string";
@ -44,6 +47,8 @@ public class ChargingPileBinaryHandler implements ClientBinaryHandler {
// private static final String DATA_TYPE_HEX = "hex";
private final ServiceMainLogic servicemainLogic;
@Autowired
private PileOrderService pileOrderService;
public ChargingPileBinaryHandler() {
@ -75,12 +80,12 @@ public class ChargingPileBinaryHandler implements ClientBinaryHandler {
}
process(handler, d);
}
} catch (TxException | NacosException e) {
} catch (TxException | NacosException | InterruptedException e) {
log.error(e.getMessage(), e);
}
}
private void process(ClientHandler handler, byte[] data) throws TxException, IOException, NacosException {
private void process(ClientHandler handler, byte[] data) throws TxException, IOException, NacosException, InterruptedException {
String serviceName = toHex(data, 5, 6);
String version = ChargingPileServer.getVersion(handler.getName());
@ -94,11 +99,13 @@ public class ChargingPileBinaryHandler implements ClientBinaryHandler {
String pilekey = "pile:".concat(pileNo);
Map<String, Object> cachePile = REDIS.getCacheMap(pilekey);
if (SERVICE_REGISTER.equals(serviceName) && OK.equals(resultCode)) {
cachePile.put("tf", false);
cachePile.put("tcfg", false);
REDIS.setCacheMap(pilekey, cachePile);
regHandler(handler, pileNo, req);
} else if (SERVICE_RMCR.equals(serviceName) && OK.equals(resultCode)) {
setCachePileRM(pilekey);
} else if (SERVICE_OD.equals(serviceName) && OK.equals(resultCode)) {
// pileOrderService.pileEndOrder(); todo
}
if (result.getBinary() != null) {
log.info("server send msg >>>> ({}) |{}|", pileNo, toHex(result.getBinary()));
@ -108,13 +115,14 @@ public class ChargingPileBinaryHandler implements ClientBinaryHandler {
} else if (SERVICE_HB.equals(serviceName) && OK.equals(resultCode)) {
Boolean timeconfigured = (Boolean) cachePile.get("tf");
if (!timeconfigured) {
Thread.sleep(500);
Date date = Calendar.getInstance().getTime();
String timebin = getTimeBin(seqHex(pilekey.concat("seqhex")), pileNo, date);
cachePile.put("configTime", DateUtil.format(date, UTC_SIMPLE_PATTERN));
cachePile.put("configTime", DateUtil.format(date, NORM_DATETIME_FORMAT));
REDIS.setCacheMap(pilekey, cachePile);
log.info("server send time config msg >>>> ({}) |{}|", pileNo, timebin);
handler.sendClientBinary(HexUtils.toBytes(timebin));
cachePile.put("tf", true);
cachePile.put("tcfg", true);
REDIS.setCacheMap(pilekey, cachePile);
}
}

View File

@ -7,8 +7,7 @@ import cn.hutool.core.date.DateUtil;
import java.util.Calendar;
import java.util.Date;
import static cn.hutool.core.date.DatePattern.UTC_SIMPLE_MS_PATTERN;
import static cn.hutool.core.date.DatePattern.UTC_SIMPLE_PATTERN;
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMAT;
public class CP56Time2a {
@ -93,9 +92,9 @@ public class CP56Time2a {
System.out.println(String.format("--未编码--: %s", time));
String hex = toCp56Hex(time);
System.out.println("--编码1--:" + hex);
System.out.println("--解码1--:" + DateUtil.format(cp56toDate(hex), UTC_SIMPLE_PATTERN));
System.out.println("--D0073211110815--:" + DateUtil.format(cp56toDate("D0073211110815"), UTC_SIMPLE_MS_PATTERN));
System.out.println("--A85B3411110815--:" + DateUtil.format(cp56toDate("A85B3411110815"), UTC_SIMPLE_MS_PATTERN));
System.out.println("--解码1--:" + DateUtil.format(cp56toDate(hex), NORM_DATETIME_FORMAT));
System.out.println("--D0073211110815--:" + DateUtil.format(cp56toDate("D0073211110815"), NORM_DATETIME_FORMAT));
System.out.println("--A85B3411110815--:" + DateUtil.format(cp56toDate("A85B3411110815"), NORM_DATETIME_FORMAT));
// String encode = encode(time);
// System.out.println(String.format("--编码2--:%s", encode));
// System.out.println("--解码2--:" + decode(HexUtils.toBytes(encode)));

View File

@ -5,7 +5,7 @@ import cn.hutool.core.date.DateUtil;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import static cn.hutool.core.date.DatePattern.UTC_SIMPLE_PATTERN;
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMAT;
import static com.xhpc.common.core.utils.StringUtils.capitalize;
import static com.xhpc.pp.utils.security.CP56Time2a.cp56toDate;
@ -19,9 +19,13 @@ public class CacheDataUtils {
String srcval = (String) srcclz.getMethod("get".concat(capitalize(tarFieldName))).invoke(srcobj);
Object tarval;
if (tarfield.getType().getSimpleName().equals("Integer")) {
if (srcval.length() == 2) {
tarval = Integer.parseInt(srcval, 16);
} else {
tarval = HexUtils.reverseHexInt(srcval);
}
} else if (tarFieldName.contains("ime")) {
tarval = DateUtil.format(cp56toDate(srcval), UTC_SIMPLE_PATTERN);
tarval = DateUtil.format(cp56toDate(srcval), NORM_DATETIME_FORMAT);
} else {
tarval = srcval;
}