新增远程更新桩程序接口

This commit is contained in:
panshuling321 2022-06-15 14:18:16 +08:00
parent 08d85c37a1
commit 6c43b748ad
5 changed files with 212 additions and 34 deletions

View File

@ -68,32 +68,32 @@
</resultMap>
<sql id="Base_Column_List">
ho.clearing_order_id, ho.charging_station_id, ho.charge_order_id, ho.user_id, ho.terminal_id, ho.serial_number,
ho.internet_serial_number,
ifnull(ho.power_price_total, 0) as 'power_price_total',
ifnull(ho.service_price_total, 0) as 'service_price_total',
ifnull(ho.total_price, 0) as 'total_price',
ifnull(ho.promotion_discount, 0) as 'promotion_discount',
ifnull(ho.act_price, 0) as 'act_price',
ifnull(ho.act_power_price, 0) as 'act_power_price',
ifnull(ho.act_service_price, 0) as 'act_service_price',
ifnull(ho.internet_commission, 0) as 'internet_commission',
ifnull( ho.internet_svc_commission, 0) as 'internet_svc_commission',
ifnull(ho.platform_commission, 0) as 'platform_commission',
ifnull(ho.platform_svc_commisssion, 0) as 'platform_svc_commisssion',
ifnull(ho.operation_commission, 0) as 'operation_commission',
ifnull(ho.operation_svc_commission, 0) as 'operation_svc_commission',
ho.start_soc, ho.end_soc, ho.reconciliation_status, ho.sorting_status, ho.`type`, ho.`status`, ho.del_flag,
ho.create_time, ho.create_by, ho.update_time, ho.update_by, ho.remark, ho.`state`, ho.vin_normal, ho.search_value,
ho.operator_id_evcs, ho.charge_model_evcs, ho.connector_power_evcs, ho.meter_value_end_evcs,
ho.meter_value_start_evcs, ho.operator_id3rdpty_evcs, ho.start_time, ho.end_time, ho.stop_reason_evcs,
ho.total_power, ho.user_name_evcs, ho.phone, ho.evcs_order_no, ho.confirm_Result, ho.rate_model_id,
ho.charging_mode,
ifnull(ho.internet_degree_commission, 0) as 'internet_degree_commission',
ho.`source`, ho.tenant_id, ho.operator_id, ho.operator_name,
ho.clearing_checkout_id, ho.check_status, ho.check_by, ho.check_time,
ifnull(ho.activity_power_price_total, 0) as 'activity_power_price_total',
ifnull(ho.activity_service_price_total, 0) as 'activity_service_price_total',
ifnull(ho.activity_total_price, 0) as 'activity_total_price'
ho.internet_serial_number,
ifnull(ho.power_price_total, 0) as 'power_price_total',
ifnull(ho.service_price_total, 0) as 'service_price_total',
ifnull(ho.total_price, 0) as 'total_price',
ifnull(ho.promotion_discount, 0) as 'promotion_discount',
ifnull(ho.act_price, 0) as 'act_price',
ifnull(ho.act_power_price, 0) as 'act_power_price',
ifnull(ho.act_service_price, 0) as 'act_service_price',
ifnull(ho.internet_commission, 0) as 'internet_commission',
ifnull( ho.internet_svc_commission, 0) as 'internet_svc_commission',
ifnull(ho.platform_commission, 0) as 'platform_commission',
ifnull(ho.platform_svc_commisssion, 0) as 'platform_svc_commisssion',
ifnull(ho.operation_commission, 0) as 'operation_commission',
ifnull(ho.operation_svc_commission, 0) as 'operation_svc_commission',
ho.start_soc, ho.end_soc, ho.reconciliation_status, ho.sorting_status, ho.`type`, ho.`status`, ho.del_flag,
ho.create_time, ho.create_by, ho.update_time, ho.update_by, ho.remark, ho.`state`, ho.vin_normal, ho.search_value,
ho.operator_id_evcs, ho.charge_model_evcs, ho.connector_power_evcs, ho.meter_value_end_evcs,
ho.meter_value_start_evcs, ho.operator_id3rdpty_evcs, ho.start_time, ho.end_time, ho.stop_reason_evcs,
ho.total_power, ho.user_name_evcs, ho.phone, ho.evcs_order_no, ho.confirm_Result, ho.rate_model_id,
ho.charging_mode,
ifnull(ho.internet_degree_commission, 0) as 'internet_degree_commission',
ho.`source`, ho.tenant_id, ho.operator_id, ho.operator_name,
ho.clearing_checkout_id, ho.check_status, ho.check_by, ho.check_time,
ifnull(ho.activity_power_price_total, 0) as 'activity_power_price_total',
ifnull(ho.activity_service_price_total, 0) as 'activity_service_price_total',
ifnull(ho.activity_total_price, 0) as 'activity_total_price'
</sql>

View File

@ -4,21 +4,37 @@ import cn.hutool.core.date.DateUtil;
import com.xhpc.common.api.dto.ChargingStationDto;
import com.xhpc.common.core.domain.R;
import com.xhpc.common.core.utils.HttpUtils;
import com.xhpc.common.enums.StationDeviceEnum;
import com.xhpc.pp.domain.XhpcDeviceMessage;
import com.xhpc.pp.logic.RateModelRequestLogic;
import com.xhpc.pp.logic.RemoteUpgradeDataLogic;
import com.xhpc.pp.mapper.XhpcDeviceMessageMapper;
import com.xhpc.pp.utils.HexUtils;
import lombok.extern.slf4j.Slf4j;
import org.quickserver.net.server.ClientHandler;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMAT;
import static cn.hutool.core.util.NumberUtil.isInteger;
import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS;
import static com.xhpc.common.data.redis.StaticBeanUtil.seqHex;
import static com.xhpc.pp.controller.ChargingController.*;
import static com.xhpc.pp.controller.ChargingController.checkPile;
import static com.xhpc.pp.controller.ChargingController.fmt;
import static com.xhpc.pp.controller.ChargingController.getRR;
import static com.xhpc.pp.server.ChargingPileBinaryHandler.getTimeBin;
import static com.xhpc.pp.server.ChargingPileServer.getHandler;
import static com.xhpc.pp.server.ChargingPileServer.removeHandler;
@ -27,6 +43,10 @@ import static com.xhpc.pp.server.ChargingPileServer.removeHandler;
@Slf4j
public class PileController {
@Resource
XhpcDeviceMessageMapper deviceMessageMapper;
@PostMapping("pile/whitelist/add/{stationId}/{version}")
public Object addWhitelist(@PathVariable("stationId") Long stationId,
@PathVariable("version") String version,
@ -133,6 +153,14 @@ public class PileController {
String configTimeReply = pk.concat(".configTimeReply");
REDIS.setCacheObject(configTimeReply, "已下发", 30L, TimeUnit.MINUTES);
r = R.ok("校时校费下发成功.");
XhpcDeviceMessage deviceMessage = new XhpcDeviceMessage();
deviceMessage.setType(StationDeviceEnum.PILE.getCode());
deviceMessage.setSerialNumber(pileNo);
deviceMessage.setRemark("充电桩计费模型请求");
deviceMessage.setStatus(0);
deviceMessage.setContent(rsmsg);
deviceMessageMapper.insertByDomain(deviceMessage);
} catch (IOException | InterruptedException e) {
r = R.fail("校时|校费下发失败,请重试.");
}
@ -148,4 +176,67 @@ public class PileController {
return r;
}
@PostMapping("pile/{pileNo}/softwareUpgrade")
public R pileSoftwareUpgrade(@PathVariable("pileNo") String pileNo) {
String pkey = "pile:".concat(pileNo);
Map<String, Object> cachePile = REDIS.getCacheMap(pkey);
R<Object> r = checkPile(cachePile);
if (r.getCode() == 200) {
String svcSrv = (String) cachePile.get("svcSrv");
String response = HttpUtils.post(fmt(svcSrv).concat("/native/pile/").concat(pileNo).concat("/softwareUpgrade"));
r = getRR(response);
}
return r;
}
@PostMapping("native/pile/{pileNo}/softwareUpgrade")
public R nativePileSoftwareUpgrade(@PathVariable("pileNo") String pileNo) {
ClientHandler handler = getHandler(pileNo);
R r = R.fail("软件更新失败,充电桩未注册,或场站费率未设置.");
if (handler != null && handler.isOpen()) {
if (!handler.isOpen()) {
log.error("send message failed. [{}]({}) connection lost", handler.getName(), pileNo);
removeHandler(pileNo);
r = R.fail("充电桩连接已断开,请稍后再试.");
} else {
String gkPattern = ("gun:").concat(pileNo).concat("*");
Collection<String> gks = REDIS.keys(gkPattern);
boolean charging = false;
for (String gk : gks) {
if (gk.length() == 20 && isInteger(REDIS.getCacheMapValue(gk, "status"))) {
charging = true;
break;
}
}
int runFlag = charging ? 2: 1;
try {
String rsmsg = RemoteUpgradeDataLogic.translate(pileNo, "0094",
"0", 0L,
"0", "0", "0",
runFlag);
handler.sendClientBinary(HexUtils.toBytes(rsmsg));
r = R.ok("软件更新下发成功.");
XhpcDeviceMessage deviceMessage = new XhpcDeviceMessage();
deviceMessage.setType(StationDeviceEnum.PILE.getCode());
deviceMessage.setSerialNumber(pileNo);
deviceMessage.setRemark("充电桩主动下发远程更新");
deviceMessage.setStatus(0);
deviceMessage.setContent(rsmsg);
deviceMessageMapper.insertByDomain(deviceMessage);
} catch (Exception e) {
r = R.fail("软件更新下发失败,请重试.");
}
}
}
return r;
}
}

View File

@ -0,0 +1,91 @@
package com.xhpc.pp.logic;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.xhpc.common.enums.StationDeviceEnum;
import com.xhpc.pp.domain.XhpcDeviceMessage;
import com.xhpc.pp.mapper.XhpcDeviceMessageMapper;
import com.xhpc.pp.tx.ServiceParameter;
import com.xhpc.pp.tx.ServiceResult;
import com.xhpc.pp.tx.logic.ServiceLogic;
import com.xhpc.pp.utils.HexUtils;
import com.xhpc.pp.utils.security.CRCCalculator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Map;
import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS;
import static com.xhpc.common.data.redis.StaticBeanUtil.seqHex;
@Lazy
@Component("RemoteUpgradeDataLogic")
public class RemoteUpgradeDataLogic implements ServiceLogic {
private static final Logger log = LoggerFactory.getLogger(RemoteUpgradeDataLogic.class);
@Resource
XhpcDeviceMessageMapper deviceMessageMapper;
@Override
public ServiceResult service(ServiceParameter sp) throws Exception {
Map<String, Object> req = sp.getParameters();
String pileNo = (String) req.get("pileNo");
Map<String, Object> cachePile = REDIS.getCacheMap("pile:".concat(pileNo));
if(!"已注册".equals(cachePile.get("status").toString())){
ObjectMapper mapper = new ObjectMapper();
ObjectNode json = mapper.createObjectNode();
json.put("error", "桩未注册");
return new ServiceResult(null, ServiceResult.FAIL, json);
}
String resultStr = translate(pileNo, "0094", "0", 0L, "0", "0", "0", 2);
String remark = "充电桩主动下发远程更新";
XhpcDeviceMessage deviceMessage = new XhpcDeviceMessage();
deviceMessage.setType(StationDeviceEnum.PILE.getCode());
deviceMessage.setSerialNumber(sp.getPileNo());
deviceMessage.setRemark(remark);
deviceMessage.setStatus(0);
deviceMessage.setContent(resultStr);
deviceMessageMapper.insertByDomain(deviceMessage);
return new ServiceResult(HexUtils.toBytes(resultStr), ServiceResult.OK);
}
public static String translate(String pileNo, String svc, String remoteHost, Long port, String ftpUserName, String ftpPassword, String upgradeUrl, int runFlag) {
String skey = "pile:".concat(pileNo).concat(".seqhex");
Map<String, Object> cachePile = REDIS.getCacheMap("pile:".concat(pileNo));
Long pileType = Long.parseLong(cachePile.get("equipmentType") + ""); // 桩型号01-直流, 02-交流
Long pilePower = new Double((double)cachePile.get("power")).longValue(); // 桩功率
String resultStr = "6862".concat(seqHex(skey)).concat(svc)
.concat(pileNo).concat(String.format("%02X", pileType)).concat(String.format("%04X", pilePower))
.concat(stringToAscii(remoteHost, 16)).concat(String.format("%02X", port))
.concat(stringToAscii(ftpUserName, 16)).concat(stringToAscii(ftpPassword, 16))
.concat(stringToAscii(upgradeUrl, 32)).concat(String.format("%02x", runFlag)).concat("01");
resultStr = resultStr.concat(CRCCalculator.calcCrc(resultStr));
return resultStr;
}
private static String stringToAscii(String value, int length){
StringBuilder sb = new StringBuilder();
char[] chars = value.toCharArray();
for (char aChar : chars) {
sb.append((int) aChar);
}
String resultStr = sb.toString();
if (resultStr.length() < length){
resultStr = String.format("%"+ length+"s", resultStr).replaceAll(" ", "0");
}
return resultStr;
}
}

View File

@ -1,7 +1,5 @@
package com.xhpc.pp.logic;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xhpc.common.data.up.PileConfigReplyData;
import com.xhpc.common.enums.StationDeviceEnum;
import com.xhpc.pp.domain.XhpcDeviceMessage;
import com.xhpc.pp.mapper.XhpcDeviceMessageMapper;
@ -29,9 +27,6 @@ public class RemoteUpgradeReplyDataLogic implements ServiceLogic {
public ServiceResult service(ServiceParameter sp) throws Exception {
Map<String, Object> req = sp.getParameters();
ObjectMapper objectMapper = new ObjectMapper();
PileConfigReplyData pileRateModelConfigReplyData = objectMapper.convertValue(req, PileConfigReplyData.class);
//todo
String remark = "充电桩收到远程更新应答";
XhpcDeviceMessage deviceMessage = new XhpcDeviceMessage();

View File

@ -34,5 +34,6 @@
<entry key="57" value-ref="RateModelConfigReplyDataLogic"/>
<entry key="91" value-ref="RemoteRestartReplyDataLogic"/>
<entry key="93" value-ref="RemoteUpgradeReplyDataLogic"/>
<entry key="94" value-ref="RemoteUpgradeDataLogic"/>
</util:map>
</beans>