diff --git a/xhpc-modules/xhpc-activity/src/main/resources/mapper/XhpcClearingHistoryOrderMapper.xml b/xhpc-modules/xhpc-activity/src/main/resources/mapper/XhpcClearingHistoryOrderMapper.xml index d7a92373..c0bd2b23 100644 --- a/xhpc-modules/xhpc-activity/src/main/resources/mapper/XhpcClearingHistoryOrderMapper.xml +++ b/xhpc-modules/xhpc-activity/src/main/resources/mapper/XhpcClearingHistoryOrderMapper.xml @@ -68,32 +68,32 @@ 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' diff --git a/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/controller/PileController.java b/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/controller/PileController.java index 9436d641..d63dba4a 100644 --- a/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/controller/PileController.java +++ b/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/controller/PileController.java @@ -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 cachePile = REDIS.getCacheMap(pkey); + R 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 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; + } } diff --git a/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/RemoteUpgradeDataLogic.java b/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/RemoteUpgradeDataLogic.java new file mode 100644 index 00000000..db44b07a --- /dev/null +++ b/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/RemoteUpgradeDataLogic.java @@ -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 req = sp.getParameters(); + String pileNo = (String) req.get("pileNo"); + Map 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 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; + } +} diff --git a/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/RemoteUpgradeReplyDataLogic.java b/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/RemoteUpgradeReplyDataLogic.java index ef241c6f..cda39698 100644 --- a/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/RemoteUpgradeReplyDataLogic.java +++ b/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/RemoteUpgradeReplyDataLogic.java @@ -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 req = sp.getParameters(); - ObjectMapper objectMapper = new ObjectMapper(); - PileConfigReplyData pileRateModelConfigReplyData = objectMapper.convertValue(req, PileConfigReplyData.class); - //todo String remark = "充电桩收到远程更新应答"; XhpcDeviceMessage deviceMessage = new XhpcDeviceMessage(); diff --git a/xhpc-modules/xhpc-power-pile/src/main/resources/svcmainlogic.xml b/xhpc-modules/xhpc-power-pile/src/main/resources/svcmainlogic.xml index 796d939e..6a29cbe2 100644 --- a/xhpc-modules/xhpc-power-pile/src/main/resources/svcmainlogic.xml +++ b/xhpc-modules/xhpc-power-pile/src/main/resources/svcmainlogic.xml @@ -34,5 +34,6 @@ +