完善充电流程;检查下发费率模型;代码重构优化

This commit is contained in:
ZZ 2021-08-09 16:24:09 +08:00
parent a94677d5b1
commit fae04fa29f
13 changed files with 152 additions and 122 deletions

View File

@ -1,39 +0,0 @@
package com.xhpc.common.data.redis;
public class CachePile {
private Long chargingStationId;
private Long rateModelId;
private Long pileNo;
public Long getChargingStationId() {
return chargingStationId;
}
public void setChargingStationId(Long chargingStationId) {
this.chargingStationId = chargingStationId;
}
public Long getRateModelId() {
return rateModelId;
}
public void setRateModelId(Long rateModelId) {
this.rateModelId = rateModelId;
}
public Long getPileNo() {
return pileNo;
}
public void setPileNo(Long pileNo) {
this.pileNo = pileNo;
}
}

View File

@ -12,7 +12,7 @@ import java.util.List;
import java.util.Map;
import static com.xhpc.common.core.utils.GetIpAndPort.getLocalIP;
import static com.xhpc.pp.logic.RegisterLogic.DISCONNECTED;
import static com.xhpc.pp.logic.RegisterLogic.REGISTERED;
import static com.xhpc.pp.server.ChargingPileServer.REDIS;
@Configuration
@ -41,7 +41,7 @@ public class EarlierBeanConf {
String status = (String) cachePile.get("status");
for (Instance i : ppInstances) { // todo make HBLogic work
if (i.getIp().concat("#").concat(Integer.valueOf(i.getPort()).toString()).equals(server)) {
if (!DISCONNECTED.equals(status)) {
if (REGISTERED.equals(status)) {
return false;
}
}

View File

@ -28,6 +28,7 @@ import static com.xhpc.common.data.redis.SeqUtil.seqHex;
import static com.xhpc.pp.logic.RegisterLogic.REGISTERED;
import static com.xhpc.pp.server.ChargingPileServer.*;
import static com.xhpc.pp.utils.security.HexUtils.toHexInt;
import static com.xhpc.pp.utils.security.HexUtils.toHexIntX;
@RestController
public class ChargingController {
@ -52,32 +53,28 @@ public class ChargingController {
String pkey = "pile:".concat(pileNo);
Map<String, Object> cachePile = REDIS.getCacheMap(pkey);
R<Object> r = R.ok();
if (cachePile.isEmpty()) {
r = R.fail("充电桩未注册");
if (cachePile == null) {
return R.fail("充电桩未注册");
}
String status = cachePile.get("status").toString();
if (!REGISTERED.equals(status)) {
r = R.fail("充电桩离线");
return R.fail("充电桩离线");
}
if (r.getCode() == 200) {
Long stationId = Long.valueOf(cachePile.get("stationId").toString()); //todo
Long stationId = (Long) cachePile.get("stationId"); //todo
ChargingStationDto cacheStation = REDIS.getCacheObject("station:".concat(stationId.toString()));
Long stationRateModelId = cacheStation.getRateModelId();
Long pileRateModelId;
String pileRateModelIdStr = (String) cachePile.get("rateModelId");
if (pileRateModelIdStr == null) {
Long pileRateModelId = (Long) cachePile.get("rateModelId");
if (pileRateModelId == null) {
pileRateModelId = stationRateModelId;
} else {
pileRateModelId = Long.parseLong(pileRateModelIdStr);
}
cachePile.put("rateModelId", pileRateModelId.toString());
cachePile.put("rateModelId", pileRateModelId);
if (!pileRateModelId.equals(stationRateModelId)) {
if (cachePile.get("status").equals("Registered")) {
if (cachePile.get("status").toString().equals(REGISTERED)) {
CacheRateModel cacheRateModel = REDIS.getCacheObject("rateModel:".concat(stationRateModelId.toString()));
String rateModel = RateModelRequestLogic.translate(cacheRateModel);
String rateModelMsg = "680E0000000A".concat(pileNo)
.concat(String.format("%04d", stationRateModelId))
.concat(toHexIntX(Math.toIntExact(stationRateModelId)))
.concat(rateModel)
.concat(ServiceResult.HEX_OK);
rateModelMsg = rateModelMsg.concat(CRCCalculator.calcCrc(rateModel));
@ -91,8 +88,9 @@ public class ChargingController {
r = R.fail("费率模型下发失败,未更新或下发等待设置中");
}
}
} else {
r = R.fail("充电桩离线,费率模型未更新或下发");
}
r = R.fail("费率模型未更新或下发");
} else {
String svcSrv = (String) cachePile.get("svcSrv");
JSONObject json = (JSONObject) JSON.toJSON(startChargingData);

View File

@ -38,7 +38,6 @@ public class PileController {
for (String pileNo : pileNoSet) {
String pkey = "pile:".concat(pileNo);
Map<String, Object> cachePile = REDIS.getCacheMap(pkey);
cachePile.put("rateModelId", cacheStation.getRateModelId());
cachePile.put("stationId", stationId);
REDIS.setCacheMap(pkey, cachePile);
}

View File

@ -1,6 +1,7 @@
package com.xhpc.pp.logic;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xhpc.common.api.dto.ChargingStationDto;
import com.xhpc.common.data.up.PileConfigReplyData;
import com.xhpc.pp.tx.ServiceParameter;
import com.xhpc.pp.tx.ServiceResult;
@ -16,10 +17,10 @@ import static com.xhpc.pp.server.ChargingPileServer.REDIS;
import static com.xhpc.pp.tx.ServiceResult.HEX_OK;
@Lazy
@Component("PileRateModelConfigReplyDataLogic")
public class PileRateModelConfigReplyDataLogic implements ServiceLogic {
@Component("RateModelConfigReplyDataLogic")
public class RateModelConfigReplyDataLogic implements ServiceLogic {
private static Logger log = LoggerFactory.getLogger(PileRateModelConfigReplyDataLogic.class);
private static Logger log = LoggerFactory.getLogger(RateModelConfigReplyDataLogic.class);
@Override
public ServiceResult service(ServiceParameter sp) throws Exception {
@ -27,12 +28,14 @@ public class PileRateModelConfigReplyDataLogic implements ServiceLogic {
Map<String, Object> req = sp.getParameters();
ObjectMapper objectMapper = new ObjectMapper();
PileConfigReplyData pileRateModelConfigReplyData = objectMapper.convertValue(req, PileConfigReplyData.class);
if (pileRateModelConfigReplyData.getConfigResult().equals(HEX_OK)) {
String pileNo = pileRateModelConfigReplyData.getPileNo();
Map<String, Object> cacheMap = REDIS.getCacheMap("pile:".concat(pileNo));
cacheMap.get("");//todo
String configResult = pileRateModelConfigReplyData.getConfigResult();
if (configResult.equals(HEX_OK)) {
// 确定设置成功的rateModelId 可能涉及协议修改
Map<String, Object> cachePile = REDIS.getCacheMap("pile:".concat(pileRateModelConfigReplyData.getPileNo()));
ChargingStationDto cacheStation = REDIS.getCacheObject("station:".concat(cachePile.get("stationId").toString()));
cachePile.put("rateModelId", cacheStation.getRateModelId());
}
return new ServiceResult(false);
return new ServiceResult(configResult);
}
}

View File

@ -1,5 +1,7 @@
package com.xhpc.pp.logic;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.xhpc.common.api.dto.ChargingStationDto;
import com.xhpc.common.data.redis.CacheRateModel;
import com.xhpc.pp.tx.ServiceParameter;
@ -29,16 +31,19 @@ public class RateModelRequestLogic implements ServiceLogic {
Map<String, Object> req = sp.getParameters();
String pileNo = (String) req.get("pileNo");
Map<String, Object> cachePile = REDIS.getCacheMap("pile:".concat(pileNo));
Integer stationId = (Integer) cachePile.get("stationId");
Long stationId = (Long) cachePile.get("stationId");
ChargingStationDto cacheStation = REDIS.getCacheObject("station:".concat(stationId.toString()));
Long rateModelId = cacheStation.getRateModelId();
if (rateModelId == null) {
return new ServiceResult((byte[]) null, ServiceResult.FAIL);
ObjectMapper mapper = new ObjectMapper();
ObjectNode json = mapper.createObjectNode();
json.put("error", "场站没有设置费率");
return new ServiceResult((byte[]) null, ServiceResult.FAIL, json);
}
CacheRateModel cacheRateModel = REDIS.getCacheObject("rateModel:".concat(rateModelId.toString()));
String rateModel = translate(cacheRateModel);
String resultStr = "680E0000000A".concat(pileNo)
.concat(String.format("%04d", rateModelId))
.concat(HexUtils.toHexIntX(Math.toIntExact(rateModelId)))
.concat(rateModel)
.concat(ServiceResult.HEX_OK);
resultStr = resultStr.concat(CRCCalculator.calcCrc(resultStr));

View File

@ -30,7 +30,7 @@ public class RateModelValidateLogic implements ServiceLogic {
String resultCode = ServiceResult.OK;
String hexCode = ServiceResult.HEX_OK;
Integer rateModelIdCache = cachePile.get("rateModelId");
if (Integer.parseInt(rateModelId) != rateModelIdCache) {
if (rateModelIdCache != Integer.parseInt(rateModelId, 16)) {
hexCode = ServiceResult.HEX_FAIL;
resultCode = ServiceResult.FAIL;
}

View File

@ -1,5 +1,6 @@
package com.xhpc.pp.logic;
import com.xhpc.pp.config.EarlierBeanConf;
import com.xhpc.pp.tx.ServiceParameter;
import com.xhpc.pp.tx.ServiceResult;
import com.xhpc.pp.tx.logic.ServiceLogic;
@ -33,20 +34,41 @@ public class RegisterLogic implements ServiceLogic {
String pileNo = (String) req.get("pileNo");
Set<String> whitelist = REDIS.getCacheSet("PILE_WHITELIST");
if (!whitelist.contains(pileNo)) {
log.info("pile not in whitelist ({}) ", pileNo);
hexCode = ServiceResult.HEX_FAIL;
resultCode = ServiceResult.FAIL;
}
int gunNum = Integer.parseInt(req.get("gunNum").toString());
for (int gunN = 1; gunN <= gunNum; gunN++) {
String gunId = String.format("%02d", (int) gunN);
String gunkey = "gun:".concat(pileNo.concat(gunId));
Map<String, Object> cacheGun = REDIS.getCacheMap(gunkey);
cacheGun.put("svcSrv", getLocalIPAndPort());
REDIS.setCacheMap(gunkey, cacheGun);
} else if (!EarlierBeanConf.ifreg(pileNo)) {
log.info("pile already registered ({}) ", pileNo);
hexCode = ServiceResult.HEX_FAIL;
resultCode = ServiceResult.FAIL;
} else {
String pkey = "pile:".concat(pileNo);
Map<String, Object> cachePile = REDIS.getCacheMap(pkey);
cachePile.put("status", REGISTERED);
String localIPAndPort = getLocalIPAndPort();
cachePile.put("svcSrv", localIPAndPort);
REDIS.setCacheMap("pile:".concat(pileNo), cachePile);
cachePileGunSvcSrv(pileNo);
int gunNum = Integer.parseInt(req.get("gunNum").toString());
for (int gunN = 1; gunN <= gunNum; gunN++) {
String gunId = String.format("%02d", gunN);
String gunkey = "gun:".concat(pileNo.concat(gunId));
Map<String, Object> cacheGun = REDIS.getCacheMap(gunkey);
cacheGun.put("svcSrv", localIPAndPort);
REDIS.setCacheMap(gunkey, cacheGun);
}
}
String resultStr = "680C00000002".concat(pileNo).concat(hexCode);
resultStr = resultStr.concat(CRCCalculator.calcCrc(resultStr));
return new ServiceResult(HexUtils.toBytes(resultStr), resultCode);
}
private void cachePileGunSvcSrv(String key) {
String svcKey = "svcSrvPile:".concat(getLocalIPAndPort());
Set<String> svcPileGuns = REDIS.getCacheSet(svcKey);
svcPileGuns.add(key);
REDIS.setCacheSet(svcKey, svcPileGuns);
}
}

View File

@ -1,7 +1,7 @@
package com.xhpc.pp.server;
import com.alibaba.nacos.api.exception.NacosException;
import com.xhpc.pp.config.EarlierBeanConf;
import com.xhpc.common.api.dto.ChargingStationDto;
import com.xhpc.pp.domain.ServiceField;
import com.xhpc.pp.logic.FieldLogic;
import com.xhpc.pp.logic.ServiceMainLogic;
@ -17,10 +17,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.xhpc.pp.config.EarlierBeanConf.getLocalIPAndPort;
import static com.xhpc.pp.logic.RegisterLogic.REGISTERED;
import static com.xhpc.pp.server.ChargingPileServer.REDIS;
import static com.xhpc.pp.tx.ServiceResult.OK;
import static com.xhpc.pp.utils.security.CRCCalculator.calcCrc;
@ -31,6 +32,8 @@ 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_RMCR = "57";
private static final String DATA_TYPE_STRING = "string";
private static final String DATA_TYPE_INT = "int";
@ -85,46 +88,36 @@ public class ChargingPileBinaryHandler implements ClientBinaryHandler {
ServiceParameter sp = new ServiceParameter(serviceName, pileNo, req);
ServiceResult result = servicemainLogic.process(sp);
String resultCode = result.getCode();
String pilekey = "pile:".concat(pileNo);
if (SERVICE_REGISTER.equals(serviceName) && OK.equals(resultCode)) {
reg(handler, pileNo, req);
} /*else if (SERVICE_HB.equals(serviceName)) {
// TODO: 2021/7/28
}*/
regHandler(handler, pileNo, req);
} else if (SERVICE_RMCR.equals(serviceName) && OK.equals(resultCode)) {
setCachePileRM(pilekey);
}
// } else if (SERVICE_HB.equals(serviceName)) {
// TODO
// }
if (result.getBinary() != null) {
log.info("server send msg >>>> ({}) |{}|", pileNo, HexUtils.toHex(result.getBinary()));
handler.sendClientBinary(result.getBinary());
if (SERVICE_RMR.equals(serviceName) && OK.equals(resultCode)) {
setCachePileRM(pilekey);
}
}
}
private void reg(ClientHandler handler, String pileNo, Map<String, Object> req) throws NacosException {
private void regHandler(ClientHandler handler, String pileNo, Map<String, Object> req) throws NacosException {
if (!EarlierBeanConf.ifreg(pileNo)) {
log.info("pile already registered >>>> ({}) ", pileNo);
return;
}
ChargingPileServer.putHandler(pileNo, handler);
ChargingPileServer.putVersion(handler.getName(), (String) req.get("version"));
String pkey = "pile:".concat(pileNo);
Map<String, Object> pileCache = REDIS.getCacheMap(pkey);
pileCache.put("status", REGISTERED);
pileCache.put("svcSrv", getLocalIPAndPort());
REDIS.setCacheMap(pkey, pileCache);
cachePileGunSvcSrv("svcSrvPile:", pileNo);
int gunNum = Integer.parseInt(req.get("gunNum").toString());
for (int gunN = 1; gunN <= gunNum; gunN++) {
String gunId = String.format("%02d", (int) gunN);
String gunkey = pileNo.concat(gunId);
cachePileGunSvcSrv("svcSrvGun:", gunkey);
}
log.info("pile registering >>>> ({}) ", pileNo);
}
private void cachePileGunSvcSrv(String prefix, String key) {
private void setCachePileRM(String pilekey) {
String svcKey = prefix.concat(getLocalIPAndPort());
Set<String> svcPileGuns = REDIS.getCacheSet(svcKey);
svcPileGuns.add(key);
REDIS.setCacheSet(svcKey, svcPileGuns);
Map<String, Object> cachePile = REDIS.getCacheMap(pilekey);
ChargingStationDto cacheStation = REDIS.getCacheObject("station:".concat(cachePile.get("stationId").toString()));
cachePile.put("rateModelId", cacheStation.getRateModelId());
REDIS.setCacheMap(pilekey, cachePile);
}
private List<byte[]> parseDataList(byte[] data) {

View File

@ -1,5 +1,6 @@
package com.xhpc.pp.server;
import com.xhpc.pp.logic.RegisterLogic;
import org.quickserver.net.server.ClientEventHandler;
import org.quickserver.net.server.ClientHandler;
import org.slf4j.Logger;
@ -7,6 +8,10 @@ import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import java.util.Map;
import static com.xhpc.pp.server.ChargingPileServer.REDIS;
@Lazy(false)
@Component
public class ChargingPileEventHandler implements ClientEventHandler {
@ -20,14 +25,18 @@ public class ChargingPileEventHandler implements ClientEventHandler {
@Override
public void gotConnected(ClientHandler handler) {
log.info("got connected -> " + handler.getName() + " <-" + handler.getSocket().getRemoteSocketAddress().toString());
log.info("-> [{}] <- {}", handler.getName(), handler.getSocket().getRemoteSocketAddress().toString());
}
@Override
public void lostConnection(ClientHandler handler) {
String pileNo = ChargingPileServer.getPileNo(handler);
log.info("lost connection -> ({}) [{}] <- {}",
String pkey = "pile:".concat(pileNo);
Map<String, Object> cachePile = REDIS.getCacheMap(pkey);
cachePile.put("status", RegisterLogic.DISCONNECTED);
REDIS.setCacheMap(pkey, cachePile);
log.info("-> ({}) - [{}] <- {}",
pileNo, handler.getName(), handler.getSocket().getRemoteSocketAddress().toString());
}
@ -36,8 +45,12 @@ public class ChargingPileEventHandler implements ClientEventHandler {
String pileNo = ChargingPileServer.getPileNo(handler);
ChargingPileServer.removeHandler(pileNo);
String pkey = "pile:".concat(pileNo);
Map<String, Object> cachePile = REDIS.getCacheMap(pkey);
cachePile.put("status", RegisterLogic.DISCONNECTED);
REDIS.setCacheMap(pkey, cachePile);
handler.closeConnection();
log.info("closing connection -> " + handler.getName() + " <-");
log.info("-> ({}) - [{}] <- {}", pileNo, handler.getName(), handler.getSocket().getRemoteSocketAddress().toString());
}
}

View File

@ -13,6 +13,12 @@ public class ServiceResult {
private String code;
private byte[] binary;
private Object json;
private String msg;
public ServiceResult(String code) {
this.code = code;
}
public ServiceResult(String code, String body) {
@ -48,21 +54,13 @@ public class ServiceResult {
this.code = code;
}
public Object getJson() {
return json;
}
public void setJson(Map<String, Object> json) {
public ServiceResult(byte[] binary, String code, Object json) {
this.binary = binary;
this.code = code;
this.json = json;
}
public byte[] getBinary() {
return binary;
}
public String getCode() {
return code;
@ -73,4 +71,34 @@ public class ServiceResult {
this.code = code;
}
public byte[] getBinary() {
return binary;
}
public void setBinary(byte[] binary) {
this.binary = binary;
}
public Object getJson() {
return json;
}
public void setJson(Object json) {
this.json = json;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}

View File

@ -16,6 +16,11 @@ public class HexUtils {
return toHex(toIntBytes(String.format("%08d", dec), 8));
}
public static String toHexIntX(Integer dec) {
return toHex(Objects.requireNonNull(toBytes(String.format("%04X", dec))));
}
public static int reverseHexInt(String hex) {
byte[] data = toBytes(reverseHex(hex));
@ -180,6 +185,9 @@ public class HexUtils {
public static void main(String[] args) {
System.out.println(toHexIntX(0xffff));
System.out.println(toHexIntX(65535));
System.out.println(Integer.parseInt("FFFF", 16));
byte[] data1 = toBytes(reverseHex("FC080000"));
System.out.println(toInteger(data1, 0, 4));
// System.out.println(reverseHexInt("A0860100"));

View File

@ -31,7 +31,7 @@
<entry key="47" value-ref="OfflineCardInquiryReplyDataLogic"/>
<entry key="51" value-ref="PileConfigReplyDataLogic"/>
<entry key="55" value-ref="PileTimeConfigReplyDataLogic"/>
<entry key="57" value-ref="PileRateModelConfigReplyDataLogic"/>
<entry key="57" value-ref="RateModelConfigReplyDataLogic"/>
<entry key="91" value-ref="RemoteRestartReplyDataLogic"/>
<entry key="93" value-ref="RemoteUpgradeReplyDataLogic"/>
</util:map>