diff --git a/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/OrderDataLogic.java b/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/OrderDataLogic.java index 7c58e678..c58801ee 100644 --- a/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/OrderDataLogic.java +++ b/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/OrderDataLogic.java @@ -21,6 +21,7 @@ import java.lang.reflect.InvocationTargetException; import java.util.Map; import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS; +import static com.xhpc.pp.logic.RealtimeDataLogic.calcem; import static com.xhpc.pp.utils.security.CacheDataUtils.reflectTranslate; @Lazy @@ -54,6 +55,15 @@ public class OrderDataLogic implements ServiceLogic { cacheGun.put("orderkey", null); REDIS.setCacheMap(gunkey, cacheGun); Long rdtime = (Long) cacheOrder.get("rdtime"); + Map cachePile = REDIS.getCacheMap("pile:".concat(orderData.getPileNo())); + if (cachePile.get("version").equals("0B")) { + final String hex = orderData.getHex(); + String cdhex = hex.substring(0xA2 * 2 + 4, hex.length() - 4); + if (cdhex.length() > 0) { + cacheOrder.put("em2", calcem(cdhex)); + REDIS.setCacheMap(orderkey, cacheOrder); + } + } String resultStr = "6815".concat(req.get("seqhex").toString()).concat("0040").concat(orderNo).concat(ServiceResult.HEX_00); resultStr = resultStr.concat(CRCCalculator.calcCrc(resultStr)); diff --git a/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/RealtimeDataLogic.java b/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/RealtimeDataLogic.java index e4babcd5..ad570d5e 100644 --- a/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/RealtimeDataLogic.java +++ b/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/RealtimeDataLogic.java @@ -9,10 +9,12 @@ import com.xhpc.common.data.down.StartChargingData; import com.xhpc.common.data.redis.CacheOrderData; import com.xhpc.common.data.redis.CacheRealtimeData; import com.xhpc.common.data.up.RealtimeData; +import com.xhpc.evcs.dto.ChargeDetails; import com.xhpc.pp.controller.ChargingController; 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 org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -28,6 +30,7 @@ import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS; import static com.xhpc.pp.server.ChargingPileServer.default_version; import static com.xhpc.pp.utils.HexUtils.reverseHexInt; import static com.xhpc.pp.utils.HexUtils.toBits; +import static com.xhpc.pp.utils.security.CP56Time2a.cp56toDateStr; import static com.xhpc.pp.utils.security.CacheDataUtils.reflectTranslate; @Lazy @@ -105,8 +108,7 @@ public class RealtimeDataLogic implements ServiceLogic { Map cacheOrder = REDIS.getCacheMap(orderkey); if (!orderNo.equals("00000000000000000000000000000000")) { if (statusInt == 3) { - List realtimeDataList = (List) cacheOrder.get( - "realtimeDataList"); + List realtimeDataList = (List) cacheOrder.get("realtimeDataList"); cacheGun.put("idleCnt", 0); if (realtimeDataList == null) { realtimeDataList = new ArrayList<>(); @@ -129,7 +131,13 @@ public class RealtimeDataLogic implements ServiceLogic { Integer cacheStartSoc = (Integer) cacheOrder.get("startSoc"); if (cacheStartSoc == null && socInt != 0) cacheOrder.put("startSoc", socInt); if (socInt != 0) cacheOrder.put("endSoc", socInt); -// cacheOrder.put("em", realtimeData.()); //todo 实时时段明细数据是否由桩直接上传? + if (cachePile.get("version").equals("0B")) { + final String hex = realtimeData.getHex(); + String cdhex = hex.substring(0x40 * 2 + 4, hex.length() - 4); + if (cdhex.length() > 0) { + cacheOrder.put("em1", calcem(cdhex)); + } + } cacheOrder.put("rbalance", balance); cacheOrder.put("remainingTime", tr); cacheOrder.put("rdtime", DateUtil.calendar().getTime().getTime()); @@ -228,6 +236,24 @@ public class RealtimeDataLogic implements ServiceLogic { return new ServiceResult(false); } + public static List calcem(String hex) { + + int sumPeriod = Integer.parseInt(hex.substring(0, 2), 16); + List cds = new ArrayList<>(); + for (int i = 2; i < sumPeriod * 68 + 2; i = i + 68) { + ChargeDetails cd = new ChargeDetails(); + cd.setDetailStartTime(cp56toDateStr(hex.substring(i, i + 14))); + cd.setDetailEndTime(cp56toDateStr(hex.substring(i + 14, i + 28))); + cd.setElecPrice(HexUtils.reverseHexInt(hex.substring(i + 28, i + 36)) / 100000.0); + cd.setSevicePrice(HexUtils.reverseHexInt(hex.substring(i + 36, i + 44)) / 100000.0); + cd.setDetailPower(HexUtils.reverseHexInt(hex.substring(i + 44, i + 52)) / 10000.0); + cd.setDetailElecMoney(HexUtils.reverseHexInt(hex.substring(i + 52, i + 60)) / 10000.0); + cd.setDetailElecMoney(HexUtils.reverseHexInt(hex.substring(i + 60, i + 68)) / 10000.0); + cds.add(cd); + } + return cds; + } + private CacheRealtimeData translate(RealtimeData realtimeData) throws InvocationTargetException, IllegalAccessException, InstantiationException { diff --git a/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/RegisterLogic.java b/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/RegisterLogic.java index 69a32c7e..71125cbc 100644 --- a/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/RegisterLogic.java +++ b/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/logic/RegisterLogic.java @@ -11,7 +11,6 @@ import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; -import java.util.Collection; import java.util.Map; import java.util.Set; @@ -51,6 +50,7 @@ public class RegisterLogic implements ServiceLogic { cachePile.put("svcSrv", localIPAndPort); int gunNum = Integer.parseInt(req.get("gunNum").toString()); cachePile.put("gunNum", gunNum); + cachePile.put("version", req.get("version").toString()); REDIS.setCacheMap("pile:".concat(pileNo), cachePile); for (int gunN = 1; gunN <= gunNum; gunN++) { String gunId = String.format("%02d", gunN); @@ -62,12 +62,12 @@ public class RegisterLogic implements ServiceLogic { REDIS.setCacheMap(gunkey, cacheGun); String svcSrvKeyNew = "svcSrvGuns:".concat(getLocalIPAndPort()); cachePileGunSvcSrv(gunkey, svcSrvKeyNew); - final Collection cacheSvcSrvKeys = REDIS.keys("svcSrvGuns:*"); - for (String svcSrvKey : cacheSvcSrvKeys) { - if (!svcSrvKey.equals(svcSrvKeyNew)) { - REDIS.deleteSetVal(svcSrvKey, gunkey); - } - } +// final Collection cacheSvcSrvKeys = REDIS.keys("svcSrvGuns:*"); +// for (String svcSrvKey : cacheSvcSrvKeys) { +// if (!svcSrvKey.equals(svcSrvKeyNew)) { +// REDIS.deleteSetVal(svcSrvKey, gunkey); +// } +// } todo ucat } log.info("pile (re)registered ({}) ", pileNo); } diff --git a/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/utils/security/CP56Time2a.java b/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/utils/security/CP56Time2a.java index adb90115..63b55353 100644 --- a/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/utils/security/CP56Time2a.java +++ b/xhpc-modules/xhpc-power-pile/src/main/java/com/xhpc/pp/utils/security/CP56Time2a.java @@ -9,6 +9,7 @@ import java.util.Calendar; import java.util.Date; import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMAT; +import static com.xhpc.evcs.utils.DateUtil.DATE_FORMAT_DATE_TIME; public class CP56Time2a { @@ -32,6 +33,22 @@ public class CP56Time2a { return dt.toCalendar().getTime(); } + public static String cp56toDateStr(String hex) { + + Date date = cp56toDate(hex); + return DateTime.of(date).toString(DATE_FORMAT_DATE_TIME); + } + + public static String cp56toDateTSStr(String hex) { + + byte[] bytes = hex.getBytes(); + int[] infoElements = new int[bytes.length]; + for (int i = 0; i < bytes.length; i++) { + infoElements[i] = bytes[i]; + } + return TimeScale(infoElements); + } + public static String toCp56Hex(Date d) { byte[] result = new byte[7]; @@ -87,6 +104,123 @@ public class CP56Time2a { return builder.toString(); } + /** + * 时标CP56Time2a解析 + * + * @param b 时标CP56Time2a(长度为7 的int数组) + * @return 解析结果 + */ + public static String TimeScale(int b[]) { + + StringBuilder result = new StringBuilder(); + + int year = b[6] & 0x7F; + int month = b[5] & 0x0F; + int day = b[4] & 0x1F; + int week = (b[4] & 0xE0) / 32; + int hour = b[3] & 0x1F; + int minute = b[2] & 0x3F; + int second = (b[1] << 8) + b[0]; + + result.append("20"); + result.append(year).append("-"); + result.append(String.format("%02d", month)).append("-"); + result.append(String.format("%02d", day)).append(" "); + result.append(hour).append(":").append(minute).append(":"); + result.append(second / 1000 + "." + second % 1000); + + return result.toString(); + } + + /** + * 时间转16进制字符串 + */ + public static String date2HStr(Date date) { + + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + StringBuilder builder = new StringBuilder(); + String milliSecond = String.format("%04X", (calendar.get(Calendar.SECOND) * 1000) + calendar.get(Calendar.MILLISECOND)); + builder.append(milliSecond.substring(2, 4)); + builder.append(milliSecond.substring(0, 2)); + builder.append(String.format("%02X", calendar.get(Calendar.MINUTE) & 0x3F)); + builder.append(String.format("%02X", calendar.get(Calendar.HOUR_OF_DAY) & 0x1F)); + int week = calendar.get(Calendar.DAY_OF_WEEK); + if (week == Calendar.SUNDAY) + week = 7; + else week--; + builder.append(String.format("%02X", (week << 5) + (calendar.get(Calendar.DAY_OF_MONTH) & 0x1F))); + builder.append(String.format("%02X", calendar.get(Calendar.MONTH) + 1)); + builder.append(String.format("%02X", calendar.get(Calendar.YEAR) - 2000)); + return builder.toString(); + } + + + public static Date toDate(byte[] bytes) { + + int milliseconds1 = bytes[0] < 0 ? 256 + bytes[0] : bytes[0]; + int milliseconds2 = bytes[1] < 0 ? 256 + bytes[1] : bytes[1]; + int milliseconds = milliseconds1 + milliseconds2 * 256; + // 位于 0011 1111 + int minutes = bytes[2] & 0x3f; + // 位于 0001 1111 + int hours = bytes[3] & 0x1f; + // 位于 0000 1111 + int days = bytes[4] & 0x0f; + // 位于 0001 1111 + int months = bytes[5] & 0x0f; + // 位于 0111 1111 + int years = bytes[6] & 0x7f; + final Calendar aTime = Calendar.getInstance(); + aTime.set(Calendar.MILLISECOND, milliseconds); + aTime.set(Calendar.MINUTE, minutes); + aTime.set(Calendar.HOUR_OF_DAY, hours); + aTime.set(Calendar.DAY_OF_MONTH, days); + aTime.set(Calendar.MONTH, months); + aTime.set(Calendar.YEAR, years + 2000); + return aTime.getTime(); + } + + public static byte[] toBytes(Date aDate) { + + byte[] result = new byte[7]; + + final Calendar aTime = Calendar.getInstance(); + + aTime.setTime(aDate); + + final int milliseconds = aTime.get(Calendar.MILLISECOND); + + result[0] = (byte) (milliseconds % 256); + + result[1] = (byte) (milliseconds / 256); + + result[2] = (byte) aTime.get(Calendar.MINUTE); + + result[3] = (byte) aTime.get(Calendar.HOUR_OF_DAY); + + result[4] = (byte) aTime.get(Calendar.DAY_OF_MONTH); + + result[5] = (byte) aTime.get(Calendar.MONTH); + + result[6] = (byte) (aTime.get(Calendar.YEAR) % 100); + + System.out.println("Year->" + aTime.get(Calendar.YEAR)); + + return result; + + } + + private static String getCP56time2a(String hex) { + + return "20" + String.format("%02d", Integer.parseInt(hex.substring(12, 14), 16)) + "-" + + String.format("%02d", Integer.parseInt(hex.substring(10, 12), 16)) + "-" + + String.format("%02d", Integer.parseInt(hex.substring(8, 10), 16)) + "T" + + String.format("%02d", Integer.parseInt(hex.substring(6, 8), 16)) + ":" + + String.format("%02d", Integer.parseInt(hex.substring(4, 6), 16)) + ":" + + String.format("%02d", Integer.parseInt(hex.substring(2, 4) + "" + hex.substring(0, 2), 16) / 1000); + } + public static void main(String[] args) throws InterruptedException { // Date time = Calendar.getInstance().getTime();