|
|
@@ -0,0 +1,833 @@
|
|
|
+package com.tmzn.devicelinkykc.message;
|
|
|
+
|
|
|
+import com.alibaba.fastjson2.JSONArray;
|
|
|
+import com.alibaba.fastjson2.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
|
|
|
+import com.tmzn.devicelinkykc.constant.DeviceOnlineStatus;
|
|
|
+import com.tmzn.devicelinkykc.constant.PortStatusConstant;
|
|
|
+import com.tmzn.devicelinkykc.constant.RedisConstant;
|
|
|
+import com.tmzn.devicelinkykc.constant.ykc.BillingModelConst;
|
|
|
+import com.tmzn.devicelinkykc.constant.ykc.StatusConstant;
|
|
|
+import com.tmzn.devicelinkykc.constant.ykc.TransConstant;
|
|
|
+import com.tmzn.devicelinkykc.entity.*;
|
|
|
+import com.tmzn.devicelinkykc.frameMsg.DataConversion;
|
|
|
+import com.tmzn.devicelinkykc.frameMsg.FrameDataSplicing;
|
|
|
+import com.tmzn.devicelinkykc.frameMsg.TransMoney;
|
|
|
+import com.tmzn.devicelinkykc.frameMsg.frameType.CharngingPushFrame;
|
|
|
+import com.tmzn.devicelinkykc.frameMsg.frameType.LoginFrame;
|
|
|
+import com.tmzn.devicelinkykc.frameMsg.frameType.RealTimeStatusPushFrame;
|
|
|
+import com.tmzn.devicelinkykc.frameMsg.frameType.TransactionFlowPushFrame;
|
|
|
+import com.tmzn.devicelinkykc.msgEnum.DeviceSendYkc;
|
|
|
+import com.tmzn.devicelinkykc.redis.RedisCache;
|
|
|
+import com.tmzn.devicelinkykc.service.*;
|
|
|
+import com.tmzn.devicelinkykc.socket.DeviceConnectionMsg;
|
|
|
+import com.tmzn.devicelinkykc.socket.SocketHandle;
|
|
|
+import com.tmzn.devicelinkykc.transdata.constant.NormalChargeConstant;
|
|
|
+import com.tmzn.devicelinkykc.transdata.entity.DeviceParam;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import java.io.IOException;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author xp
|
|
|
+ * @date 2024/3/13
|
|
|
+ * @explain " 设备消息处理 "
|
|
|
+ * //TODO:考虑设备上来的消息只走数据库查询不走redis订阅数据
|
|
|
+ */
|
|
|
+@Component
|
|
|
+public class DeviceMsgHandle {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private DeviceStatusService deviceStatusService;
|
|
|
+ @Autowired
|
|
|
+ private SocketHandle socketHandle;
|
|
|
+ @Autowired
|
|
|
+ private RedisCache redisCache;
|
|
|
+ @Autowired
|
|
|
+ private RealTimeStatusPushFrame realTimeStatusPushFrame;
|
|
|
+ @Autowired
|
|
|
+ private TransactionFlowPushFrame transactionFlowPushFrame;
|
|
|
+ @Autowired
|
|
|
+ private LoginFrame loginFrame;
|
|
|
+ @Autowired
|
|
|
+ private CharngingPushFrame charngingPushFrame;
|
|
|
+ @Autowired
|
|
|
+ private DeviceService deviceService;
|
|
|
+ @Autowired
|
|
|
+ private OrderStatusService orderStatusService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private DeviceControlerService deviceControlerService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private BillingModelService billingModelService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private TransMoney transMoney;
|
|
|
+
|
|
|
+ private static final Logger logger = LoggerFactory.getLogger(DeviceMsgHandle.class);
|
|
|
+ private Long lastLogTime;
|
|
|
+ private static final Long gap = 1000 * 30L;
|
|
|
+ private static final BigDecimal zero = new BigDecimal("0");
|
|
|
+
|
|
|
+ public void deviceMsg(String msg) throws Exception{
|
|
|
+ //必须过滤调非云快充设备
|
|
|
+
|
|
|
+
|
|
|
+ //logger.info("redis中msg>>>" + msg);
|
|
|
+ msg = msg.substring(1, msg.length() - 1);
|
|
|
+ msg = msg.replace("\\", "");
|
|
|
+ checkActive(msg);
|
|
|
+
|
|
|
+ JSONObject jsonObject = null;
|
|
|
+ try {
|
|
|
+
|
|
|
+ jsonObject = JSONObject.parseObject(msg);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ //这里正常格式才走,不正常的格式不打印报错了;可能有其他格式的数据过来;正常要解析的数据是能走到JSON中的
|
|
|
+ logger.info("device msg conversion exception not processed!!!" + msg);
|
|
|
+
|
|
|
+ return;
|
|
|
+ //e.printStackTrace();
|
|
|
+ }
|
|
|
+ if (!redisCache.hasKey(RedisConstant.DEVICE_INFO)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ Set<String> setImei = redisCache.getCacheObject(RedisConstant.DEVICE_INFO);
|
|
|
+ String imei = jsonObject.getString("imei");
|
|
|
+ if (!(imei != null && setImei.contains(imei))) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+/* JSONArray data = jsonObject.getJSONArray("data");
|
|
|
+ Integer[] a = new Integer[data.size()];
|
|
|
+ for (int i = 0; i < data.size(); i++) {
|
|
|
+ a[i] = data.getIntValue(i);
|
|
|
+ }
|
|
|
+ List<Integer> ints = Arrays.asList(a);
|
|
|
+ if (ints.contains(113)) {
|
|
|
+ //特殊情况113,{"port":1,"paytype":1,"reason":1,"balance":0,"elec":52},
|
|
|
+ //113的位置
|
|
|
+ System.out.println("113index>" + ints.indexOf(113));
|
|
|
+ int port = a[ints.indexOf(113) + 1];
|
|
|
+ int paytype = a[ints.indexOf(113) + 2];
|
|
|
+ int reason = a[ints.indexOf(113) + 3];
|
|
|
+ int elec1 = a[ints.indexOf(113) + 7];
|
|
|
+ int elec12 = a[ints.indexOf(113) + 8] << 8;
|
|
|
+ int elec = elec1 + elec12;
|
|
|
+ String aaa = "{\"real_data\":{\"port\":" + port + ",\"paytype\":" + paytype + ",\"reason\":" + reason + ",\"balance\":0,\"elec\":" + elec + "},\"type\":113}";
|
|
|
+ JSONObject realdata = JSONObject.parseObject(aaa);
|
|
|
+ System.out.println(realdata);
|
|
|
+// jsonObject.remove("real_data");
|
|
|
+// jsonObject.put("real_data");
|
|
|
+ jsonObject = realdata;
|
|
|
+ }*/
|
|
|
+ logger.info("msg>>>" + msg);
|
|
|
+ //设备状态更新,true:没有type不是设备上送类型不往云快充处理 false:需要根据设备消息类型往下处理是不是需要上报云快充
|
|
|
+ if (checkDeviceStatus(jsonObject)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void checkActive(String s) {
|
|
|
+
|
|
|
+ Long now = System.currentTimeMillis();
|
|
|
+ if (lastLogTime == null) {
|
|
|
+ lastLogTime = now;
|
|
|
+ }
|
|
|
+ Long gap = now - lastLogTime;
|
|
|
+ if (gap > gap) {
|
|
|
+ //logger.info("message:,{}", s);
|
|
|
+ lastLogTime = now;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设备状态按照设备上报和设备心跳上送时间校验修改,这里就必须更新状态的修改时间;通过定时任务判断在线设备接收心跳包超10分钟改为离线
|
|
|
+ *
|
|
|
+ * @param jsonObject
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean checkDeviceStatus(JSONObject jsonObject) throws Exception {
|
|
|
+ String imei = jsonObject.getString("imei");
|
|
|
+
|
|
|
+ Integer cmd = jsonObject.getInteger("cmd");
|
|
|
+ if (!jsonObject.containsKey("type")) {
|
|
|
+ //TODO:离线判断:设备上报+?设备心跳时间校验?
|
|
|
+ //没有type但是cmd指令是离线时37896=========
|
|
|
+ if (cmd == 37896) {
|
|
|
+ QueryWrapper<DeviceStatus> deviceStatusQueryWrapper = new QueryWrapper<>();
|
|
|
+ deviceStatusQueryWrapper.eq("device_imei", imei);
|
|
|
+ List<DeviceStatus> list = deviceStatusService.list(deviceStatusQueryWrapper);
|
|
|
+ if (list.size() > 0) {
|
|
|
+ for (DeviceStatus deviceStatus : list) {
|
|
|
+ //deviceStatus.setInsertGunStatus(StatusConstant.INSERT_GUNS_NO);
|
|
|
+ //deviceStatus.setGunStatus(StatusConstant.OFFLINE);
|
|
|
+ deviceStatus.setOnlineStatus(DeviceOnlineStatus.OFFLINE);
|
|
|
+ deviceStatus.setUpdateTime(System.currentTimeMillis());
|
|
|
+ deviceStatusService.updateById(deviceStatus);
|
|
|
+ if (socketHandle.existDeviceConnection(deviceStatus.getPileCode())) {
|
|
|
+ String pilecode = deviceStatus.getPileCode();
|
|
|
+ DeviceConnectionMsg deviceConnection = socketHandle.getDeviceConnection(pilecode);
|
|
|
+ byte[] transactionNum = new byte[16]; //FrameDataSplicing.transactionNum(pilecode, deviceConnection.getMessageCount());
|
|
|
+ if (deviceStatus.getGunStatus() == PortStatusConstant.EMERGENCY_STOP) {
|
|
|
+ deviceStatus.setGunStatus(StatusConstant.FREE);
|
|
|
+ }
|
|
|
+ realTimeStatusPushFrame.deviceStatusPush(deviceConnection, transactionNum, pilecode, (byte) deviceStatus.getGunPort(), deviceStatus.getGunStatus(), deviceStatus.getInsertGunStatus(), 0, 0, zero, zero, 0);
|
|
|
+ socketHandle.removeDeviceConnection(deviceStatus.getPileCode());
|
|
|
+ redisCache.deleteObject(RedisConstant.DEVICE_PORT_STATUS + imei);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ Integer type = jsonObject.getInteger("type");
|
|
|
+ //TODO:设备状态的修改这里进行监听变化 ,?? 1.设备消息cmd:75960设备上报消息是的命令,只要设备报的不是离线当做设备在线 2.设备上报指令后根据type类型来分类处理消息包括:设备设为在线 是否插枪状态 枪状态(端口状态)
|
|
|
+ if (NormalChargeConstant.CMD_SET_MAINBOARD.equals(cmd)) {
|
|
|
+
|
|
|
+ if (NormalChargeConstant.KEY_PORT_DETAIL.equals(type)) {
|
|
|
+ //103状态是带电压功率等信息的,所以需要对该信息进行处理操作
|
|
|
+ JSONObject data = jsonObject.getJSONObject("real_data");
|
|
|
+ Integer port_first_status = data.getInteger("port_first_status");
|
|
|
+ Integer port_second_status = data.getInteger("port_second_status");
|
|
|
+ Integer power = data.getInteger("power");
|
|
|
+
|
|
|
+ //功率为0时,还是充电中状态,将状态转换成空闲,结束充电
|
|
|
+// 20240608现场使用时出现充电状态第一次103上来就是power是0情况
|
|
|
+// if (port_first_status != null&&power==0&&port_first_status==PortStatusConstant.CHARGING){
|
|
|
+// port_first_status=PortStatusConstant.FREE;
|
|
|
+// }
|
|
|
+// if (port_second_status != null&&power==0&&port_second_status==PortStatusConstant.CHARGING){
|
|
|
+// port_second_status=PortStatusConstant.FREE;
|
|
|
+// }
|
|
|
+ redisCache.setCacheObject(RedisConstant.DEVICE_PORT_STATUS + imei, data, 15, TimeUnit.MINUTES);
|
|
|
+ if (port_first_status != null) {
|
|
|
+ checkPort(port_first_status, 1, imei, type);
|
|
|
+ }
|
|
|
+ if (port_second_status != null) {
|
|
|
+ checkPort(port_second_status, 2, imei, type);
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if (NormalChargeConstant.PORT_STATUS.equals(type)) {
|
|
|
+ //116端口详情也会变化
|
|
|
+ JSONArray data = jsonObject.getJSONArray("data");
|
|
|
+ checkPort(data.getInteger(4), data.getInteger(3), imei, type);
|
|
|
+ } else if (NormalChargeConstant.KEY_PORT_STATUS.equals(type)) {
|
|
|
+ //状态查询101
|
|
|
+ JSONObject data = jsonObject.getJSONObject("real_data");
|
|
|
+ Integer port_first_status = data.getInteger("port_first_status");
|
|
|
+ Integer port_second_status = data.getInteger("port_second_status");
|
|
|
+ if (port_first_status != null) {
|
|
|
+ checkPort(port_first_status, 1, imei, type);
|
|
|
+ }
|
|
|
+ if (port_second_status != null) {
|
|
|
+ checkPort(port_second_status, 2, imei, type);
|
|
|
+ }
|
|
|
+ } else if (NormalChargeConstant.KEY_STARTCHARGE.equals(type)) {
|
|
|
+ //开启充电设备上报结果
|
|
|
+ JSONObject data = jsonObject.getJSONObject("real_data");
|
|
|
+ Integer result = data.getInteger("result");
|
|
|
+ Integer port = data.getInteger("port");
|
|
|
+ //TODO:上报云快充启动充电结果
|
|
|
+// QueryWrapper<OrderStatus> orderStatusQueryWrapper = new QueryWrapper<>();
|
|
|
+// orderStatusQueryWrapper.eq("imei",imei).eq("guns_code",port);
|
|
|
+// OrderStatus one = orderStatusService.getOne(orderStatusQueryWrapper);
|
|
|
+// List<OrderStatus> collect = orderStatuses.stream().filter(orderStatus -> orderStatus.getGunsCode() == port).collect(Collectors.toList());
|
|
|
+// OrderStatus one = new OrderStatus();
|
|
|
+// if (collect.size()>0){
|
|
|
+// one=collect.get(0);
|
|
|
+// } else {
|
|
|
+// logger.info("开启充电未查到设备订单");
|
|
|
+// return false;
|
|
|
+// }
|
|
|
+ QueryWrapper<OrderStatus> orderStatusQueryWrapper = new QueryWrapper<>();
|
|
|
+ orderStatusQueryWrapper.eq("device_imei", imei).eq("guns_code", port).orderByDesc("create_time").last("limit 1");
|
|
|
+ OrderStatus statusServiceOne = orderStatusService.getOne(orderStatusQueryWrapper);
|
|
|
+ byte[] bytes = statusServiceOne.getTransOrder();
|
|
|
+ logger.info(statusServiceOne.getPileCode() + ":设备开启充电流水号:" + DataConversion.bytesToHexString(bytes));
|
|
|
+ DeviceConnectionMsg deviceConnection = socketHandle.getDeviceConnection(statusServiceOne.getPileCode());
|
|
|
+ int reson = 0x00;
|
|
|
+ if (result == 0x01) {
|
|
|
+ //启充成功上报充电开启成功
|
|
|
+ charngingPushFrame.startStatus(deviceConnection, bytes, port, result, 0x00);
|
|
|
+ } else {
|
|
|
+ //启机不成功,根据设备状态判断,并且要结束充电并上报订单
|
|
|
+ if (port == 1) {
|
|
|
+ if (redisCache.hasKey(RedisConstant.ONLINE_DEVICE_ONE)) {
|
|
|
+ DeviceStatus oneStatus = redisCache.getCacheMapValue(RedisConstant.ONLINE_DEVICE_ONE, statusServiceOne.getPileCode());
|
|
|
+ if (StatusConstant.FAULT == oneStatus.getGunStatus()) {
|
|
|
+ reson = 0x03;
|
|
|
+ } else if (StatusConstant.OFFLINE == oneStatus.getGunStatus()) {
|
|
|
+ reson = 0x04;
|
|
|
+ } else if (StatusConstant.CHARGING == oneStatus.getGunStatus()) {
|
|
|
+ reson = 0x02;
|
|
|
+ }
|
|
|
+ charngingPushFrame.startStatus(deviceConnection, bytes, port, result, reson);
|
|
|
+ }
|
|
|
+ } else if (port == 2) {
|
|
|
+ if (redisCache.hasKey(RedisConstant.ONLINE_DEVICE_TWO)) {
|
|
|
+ DeviceStatus oneStatus = redisCache.getCacheMapValue(RedisConstant.ONLINE_DEVICE_TWO, statusServiceOne.getPileCode());
|
|
|
+ if (StatusConstant.FAULT == oneStatus.getGunStatus()) {
|
|
|
+ reson = 0x03;
|
|
|
+ } else if (StatusConstant.OFFLINE == oneStatus.getGunStatus()) {
|
|
|
+ reson = 0x04;
|
|
|
+ } else if (StatusConstant.CHARGING == oneStatus.getGunStatus()) {
|
|
|
+ reson = 0x02;
|
|
|
+ }
|
|
|
+ charngingPushFrame.startStatus(deviceConnection, bytes, port, result, reson);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (NormalChargeConstant.KEY_END_NOTICE.equals(type)) {
|
|
|
+ //停止充电通知触发情况:1.急停,收到停充时主动要去发停充,所以这里不能处理急停的交易订单;2.手动停充,正常的远程停止指令
|
|
|
+ // 1.设备已经在接收到云快充指令的时候进行了停充操作,2.结算订单,上报云快充停止回复
|
|
|
+
|
|
|
+
|
|
|
+ try {
|
|
|
+
|
|
|
+ JSONObject data = jsonObject.getJSONObject("real_data");
|
|
|
+ logger.info("接收到设备上送113停止充电msg>>" + jsonObject.toString());
|
|
|
+ int port = data.getIntValue("port");
|
|
|
+ byte reson = data.getByte("reason");
|
|
|
+ QueryWrapper<OrderStatus> orderStatusQueryWrapper = new QueryWrapper<>();
|
|
|
+ orderStatusQueryWrapper.eq("device_imei", imei).eq("guns_code", port).orderByDesc("create_time").last("limit 1");
|
|
|
+ OrderStatus statusServiceOne = orderStatusService.getOne(orderStatusQueryWrapper);
|
|
|
+ if (NormalChargeConstant.KEY_END_NOTICE.equals(type)&&statusServiceOne.getReasonStopCharging()!=TransConstant.APP_REMOTE_STOP) {
|
|
|
+ DeviceParam dataParam = new DeviceParam();
|
|
|
+ dataParam.setDeviceId(imei);
|
|
|
+ dataParam.setCcid(imei);
|
|
|
+ deviceControlerService.sendPortDetailCmd(dataParam);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (statusServiceOne.getTransactionOrderReportingActionStatus()==StatusConstant.TRANSACTION_ORDER_REPORTING_ACTION_STATUS_OK){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //查询计费模板
|
|
|
+ QueryWrapper<BillingModel> billingModelQueryWrapper = new QueryWrapper<>();
|
|
|
+ billingModelQueryWrapper.eq("device_imei", imei);
|
|
|
+ BillingModel model = billingModelService.getOne(billingModelQueryWrapper);
|
|
|
+ //收到停充回复
|
|
|
+ DeviceConnectionMsg deviceConnection = socketHandle.getDeviceConnection(statusServiceOne.getPileCode());
|
|
|
+ if (reson == 0x01) {
|
|
|
+ if (redisCache.hasKey(RedisConstant.DEVICE_PORT_STATUS + imei)) {
|
|
|
+ //拿缓存的103状态看现在的端口状态是急停不处理113停止充电
|
|
|
+ JSONObject dataJson = redisCache.getCacheObject(RedisConstant.DEVICE_PORT_STATUS + imei);
|
|
|
+ Integer port_first_status = dataJson.getInteger("port_first_status");
|
|
|
+ Integer port_second_status = dataJson.getInteger("port_second_status");
|
|
|
+ if (port_first_status == PortStatusConstant.EMERGENCY_STOP || port_first_status == PortStatusConstant.EMERGENCY_STOP) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (statusServiceOne.getReasonStopCharging() == TransConstant.EMERGENCY_STOP_EXCEPTION_STOP || statusServiceOne.getStopChargingReply() == 1) {
|
|
|
+ //1.急停停充的逻辑不处理停止充电记录 2.一个订单多次停止也不再次上报 3.充满不拔枪113结束通知会延迟所以充满时已经处理过交易上送
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //113进到这里说明需要记录结束时间(最优时间,尽量能让后台计费的103或113落库)
|
|
|
+ statusServiceOne.setEndTime(System.currentTimeMillis());
|
|
|
+ byte[] encrypt = new byte[0];
|
|
|
+ //订单充电结束但是原因是0的一般是当手动停充处理
|
|
|
+ if (statusServiceOne.getReasonStopCharging() == 0) {
|
|
|
+ statusServiceOne.setReasonStopCharging(TransConstant.MANUAL_STOP);
|
|
|
+ }
|
|
|
+ ////计算电量费用后上报,手动停止和余额不足的情况
|
|
|
+ // DeviceStatus deviceStatus = redisCache.getCacheMapValue(RedisConstant.ONLINE_DEVICE_ONE, statusServiceOne.getPileCode());
|
|
|
+ Map<String, BigDecimal> map = transMoney.compute(port, model, statusServiceOne.getCreateTime(), statusServiceOne.getEndTime(), true);
|
|
|
+ logger.info(statusServiceOne.getPileCode() + ":停止充电上送交易记录" + DataConversion.bytesToHexString(statusServiceOne.getTransOrder()));
|
|
|
+ encrypt = transactionFlowPushFrame.sendTrans(deviceConnection, statusServiceOne.getTransOrder(), statusServiceOne.getPileCode(), (byte) 1, statusServiceOne.getCreateTime(), statusServiceOne.getEndTime(), model, statusServiceOne.getCard(), map, statusServiceOne.getReasonStopCharging());
|
|
|
+ statusServiceOne.setOriginalText(encrypt);
|
|
|
+ statusServiceOne.setStopChargingReply(StatusConstant.STOP_CHARGING_REPLY_OK);
|
|
|
+ statusServiceOne.setNowOrderStatus(StatusConstant.NOW_ORDER_STATUS_CHARGING_ENDING);
|
|
|
+ statusServiceOne.setTransactionOrderReportingActionStatus(StatusConstant.TRANSACTION_ORDER_REPORTING_ACTION_STATUS_OK);
|
|
|
+ //statusServiceOne.setEndTime(endTime);
|
|
|
+ orderStatusService.updateById(statusServiceOne);
|
|
|
+ charngingPushFrame.endStatus(deviceConnection, port, 0x01, 0x00);
|
|
|
+ } else if (reson == 0x00) {
|
|
|
+ //余额用完停充
|
|
|
+ logger.info(statusServiceOne.getPileCode() + ":设备余额不足>>>>>>停充>>>>");
|
|
|
+ DeviceParam deviceParam = new DeviceParam();
|
|
|
+ deviceParam.setDeviceId(statusServiceOne.getDeviceImei());
|
|
|
+ deviceParam.setCcid(statusServiceOne.getDeviceImei());
|
|
|
+ //deviceControlerService.sendPortDetailCmd(deviceParam);
|
|
|
+ //deviceControlerService.stopCharge(statusServiceOne.getDeviceImei(), statusServiceOne.getDeviceImei(), 1);
|
|
|
+ statusServiceOne.setEndTime(System.currentTimeMillis());
|
|
|
+ byte[] encrypt = new byte[0];
|
|
|
+ statusServiceOne.setReasonStopCharging(TransConstant.INSUFFICIENT_BALANCE_EXCEPTION_STOP);
|
|
|
+ //计算电量
|
|
|
+ Map<String, BigDecimal> map = transMoney.compute(port, model, statusServiceOne.getCreateTime(), statusServiceOne.getEndTime(), true);
|
|
|
+ encrypt = transactionFlowPushFrame.sendTrans(deviceConnection, statusServiceOne.getTransOrder(), statusServiceOne.getPileCode(), (byte) 2, statusServiceOne.getCreateTime(), statusServiceOne.getEndTime(), model, statusServiceOne.getCard(), map, statusServiceOne.getReasonStopCharging());
|
|
|
+ statusServiceOne.setOriginalText(encrypt);
|
|
|
+ statusServiceOne.setStopChargingReply(StatusConstant.STOP_CHARGING_REPLY_OK);
|
|
|
+ statusServiceOne.setNowOrderStatus(StatusConstant.NOW_ORDER_STATUS_CHARGING_ENDING);
|
|
|
+ statusServiceOne.setTransactionOrderReportingActionStatus(StatusConstant.TRANSACTION_ORDER_REPORTING_ACTION_STATUS_OK);
|
|
|
+ orderStatusService.updateById(statusServiceOne);
|
|
|
+ //return false;
|
|
|
+ }
|
|
|
+ //deviceControlerService.reset(imei, imei);
|
|
|
+ DeviceParam dataParam = new DeviceParam();
|
|
|
+ dataParam.setDeviceId(imei);
|
|
|
+ dataParam.setCcid(imei);
|
|
|
+ deviceControlerService.sendPortDetailCmd(dataParam);
|
|
|
+ } catch (Exception e) {
|
|
|
+ //TODO:测试不上传订单,报个空闲设备状态
|
|
|
+ DeviceConnectionMsg deviceConnection = socketHandle.getDeviceConnection(imei);
|
|
|
+ realTimeStatusPushFrame.deviceStatusPush(deviceConnection, FrameDataSplicing.transactionNum(deviceConnection.getDeviceId(), deviceConnection.getMessageCount()), deviceConnection.getDeviceId(), (byte) 1, StatusConstant.FREE, StatusConstant.CHARGING_INIT_STATUS_OK, 0, 0, zero, zero, 0);
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ } else if (NormalChargeConstant.EMERGENCY_STOP_CHARGING.equals(type)) {
|
|
|
+ //急停停充
|
|
|
+ JSONArray data = jsonObject.getJSONArray("data");
|
|
|
+ int port = data.getInteger(2);
|
|
|
+ int status = data.getInteger(3);
|
|
|
+ //关闭急停和急停完,停止充电,获取设备状态
|
|
|
+ DeviceParam dataParam = new DeviceParam();
|
|
|
+ dataParam.setDeviceId(imei);
|
|
|
+ dataParam.setCcid(imei);
|
|
|
+ deviceControlerService.sendPortDetailCmd(dataParam);
|
|
|
+ deviceControlerService.stopCharge(imei, imei, port);
|
|
|
+ //查询计费模板
|
|
|
+ QueryWrapper<BillingModel> billingModelQueryWrapper = new QueryWrapper<>();
|
|
|
+ billingModelQueryWrapper.eq("device_imei", imei);
|
|
|
+ BillingModel model = billingModelService.getOne(billingModelQueryWrapper);
|
|
|
+ QueryWrapper<OrderStatus> orderStatusQueryWrapper = new QueryWrapper<>();
|
|
|
+ orderStatusQueryWrapper.eq("device_imei", imei)
|
|
|
+ .eq("guns_code", port)
|
|
|
+ .orderByDesc("create_time"
|
|
|
+ ).last("limit 1");
|
|
|
+ OrderStatus statusServiceOne = orderStatusService.getOne(orderStatusQueryWrapper);
|
|
|
+ statusServiceOne.setEndTime(System.currentTimeMillis());
|
|
|
+ DeviceConnectionMsg deviceConnection = socketHandle.getDeviceConnection(statusServiceOne.getPileCode());
|
|
|
+ if (status == 1) {
|
|
|
+ byte[] encrypt = new byte[0];
|
|
|
+ if (port == 1) {
|
|
|
+ //急停停充:急停状态下:1.向设备发起结束充电,结算交易订单(交给结束充电处理;但是要考虑是急停的原因),2.上报的充电结束的订单式
|
|
|
+
|
|
|
+ Map<String, BigDecimal> map = transMoney.compute(1, model, statusServiceOne.getCreateTime(), statusServiceOne.getEndTime(), true);
|
|
|
+
|
|
|
+ logger.info(statusServiceOne.getPileCode() + ":急停停充>>>上报交易记录>>>");
|
|
|
+ encrypt = transactionFlowPushFrame.sendTrans(deviceConnection, statusServiceOne.getTransOrder(), statusServiceOne.getPileCode(), (byte) 1, statusServiceOne.getCreateTime(), statusServiceOne.getEndTime(), model, statusServiceOne.getCard(), map, TransConstant.EMERGENCY_STOP_EXCEPTION_STOP);
|
|
|
+ } else if (port == 2) {
|
|
|
+ //TODO:这里还是模拟数据上报
|
|
|
+ DeviceStatus deviceStatus = redisCache.getCacheMapValue(RedisConstant.ONLINE_DEVICE_TWO, statusServiceOne.getPileCode());
|
|
|
+
|
|
|
+ Map<String, BigDecimal> map = transMoney.compute(2, model, statusServiceOne.getCreateTime(), statusServiceOne.getEndTime(), true);
|
|
|
+ //模拟3.5千瓦
|
|
|
+ encrypt = transactionFlowPushFrame.sendTrans(deviceConnection, statusServiceOne.getTransOrder(), statusServiceOne.getPileCode(), (byte) 2, statusServiceOne.getCreateTime(), statusServiceOne.getEndTime(), model, statusServiceOne.getCard(), map, TransConstant.EMERGENCY_STOP_EXCEPTION_STOP);
|
|
|
+ }
|
|
|
+ statusServiceOne.setOriginalText(encrypt);
|
|
|
+ statusServiceOne.setReasonStopCharging(TransConstant.EMERGENCY_STOP_EXCEPTION_STOP);
|
|
|
+ statusServiceOne.setStopChargingReply(StatusConstant.STOP_CHARGING_REPLY_OK);
|
|
|
+ statusServiceOne.setNowOrderStatus(StatusConstant.NOW_ORDER_STATUS_CHARGING_ENDING);
|
|
|
+ statusServiceOne.setTransactionOrderReportingActionStatus(StatusConstant.TRANSACTION_ORDER_REPORTING_ACTION_STATUS_OK);
|
|
|
+ orderStatusService.updateById(statusServiceOne);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ } else if (type == NormalChargeConstant.REPORT_PORT_STATUS) {
|
|
|
+ //114设备主动上报
|
|
|
+ JSONArray data = jsonObject.getJSONArray("data");
|
|
|
+ Integer integer = data.getInteger(2);
|
|
|
+ if (integer > 5) {
|
|
|
+ //双枪
|
|
|
+ checkPort(data.getInteger(7), 1, imei, type);
|
|
|
+ checkPort(data.getInteger(8), 2, imei, type);
|
|
|
+ } else {
|
|
|
+ checkPort(data.getInteger(7), 1, imei, type);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设备端口状态转成云快充识别状态
|
|
|
+ *
|
|
|
+ * @param portStatus
|
|
|
+ * @param port
|
|
|
+ * @param imei
|
|
|
+ */
|
|
|
+ private void checkPort(Integer portStatus, int port, String imei, int type) throws Exception{
|
|
|
+ if (portStatus.equals(PortStatusConstant.FREE)) {
|
|
|
+ if (type == NormalChargeConstant.PORT_STATUS) {
|
|
|
+ //这里116状态是1可能是直接拔枪时的操作,直接拔枪时结束充电消息会直接上送,这里只记录停止原因不做交易订单上送
|
|
|
+ deviceOnline(imei, port, (byte) PortStatusConstant.FREE, StatusConstant.INSERT_GUNS_NO, type);
|
|
|
+ }
|
|
|
+ //处理特殊情况之后还要看枪状态变位上送
|
|
|
+ deviceOnline(imei, port, StatusConstant.FREE, StatusConstant.INSERT_GUNS_NO);
|
|
|
+ } else if (portStatus.equals(PortStatusConstant.CHARGING)) {
|
|
|
+ deviceOnline(imei, port, StatusConstant.CHARGING, StatusConstant.INSERT_GUNS_YES);
|
|
|
+ } else if (portStatus.equals(PortStatusConstant.DISABLED) || portStatus.equals(PortStatusConstant.FAULT)) {
|
|
|
+ //禁用或故障上报云快充为故障信息
|
|
|
+ deviceOnline(imei, port, StatusConstant.FAULT, StatusConstant.NO);
|
|
|
+ } else if (portStatus.equals(PortStatusConstant.INSERT_GUN) || portStatus.equals(PortStatusConstant.BOOKED)) {
|
|
|
+ deviceOnline(imei, port, StatusConstant.FREE, StatusConstant.INSERT_GUNS_YES);
|
|
|
+ } else if (portStatus.equals(PortStatusConstant.CHARGING_END)) {
|
|
|
+ //充电完成状态是7,先处理一波
|
|
|
+ logger.info("charnging Portstatus>>" + portStatus + ";type:" + type);
|
|
|
+
|
|
|
+ if (deviceOnline(imei, port, (byte) PortStatusConstant.CHARGING_END, StatusConstant.INSERT_GUNS_YES, type)){
|
|
|
+ //状态是7时,处理过订单返回才是true
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ logger.info("charnging Port>>b>>>>");
|
|
|
+ //再去保证设备状态变化处理7为空闲插枪
|
|
|
+ deviceOnline(imei, port, (byte) StatusConstant.FREE, StatusConstant.INSERT_GUNS_NO);
|
|
|
+
|
|
|
+ } else if (portStatus.equals(PortStatusConstant.EMERGENCY_STOP)) {
|
|
|
+ //急停中按要求需要上报空闲状态;急停保存原始状态
|
|
|
+ deviceOnline(imei, port, (byte) PortStatusConstant.EMERGENCY_STOP, StatusConstant.INSERT_GUNS_NO);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 端口状态是7时的特殊处理充满;端口状态是1时特殊处理直接拔枪
|
|
|
+ *
|
|
|
+ * @param imei
|
|
|
+ * @param port
|
|
|
+ * @param gunsStatus
|
|
|
+ * @param insertGunStatus
|
|
|
+ * @param type 指令类型
|
|
|
+ */
|
|
|
+ private boolean deviceOnline(String imei, int port, byte gunsStatus, byte insertGunStatus, int type) throws Exception{
|
|
|
+ logger.info("处理7状态>>>>>>");
|
|
|
+ QueryWrapper<BillingModel> billingModelQueryWrapper = new QueryWrapper<>();
|
|
|
+ billingModelQueryWrapper.eq("device_imei", imei);
|
|
|
+ BillingModel model = billingModelService.getOne(billingModelQueryWrapper);
|
|
|
+
|
|
|
+ if (model == null) {
|
|
|
+ //说明设备不是云快充设备或者还没登录,获取一次103?
|
|
|
+ DeviceParam deviceParam = new DeviceParam();
|
|
|
+ deviceParam.setDeviceId(imei);
|
|
|
+ deviceParam.setCcid(imei);
|
|
|
+ deviceControlerService.sendPortDetailCmd(deviceParam);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //只有指令116时进入处理
|
|
|
+ //20240620:所有7状态当充满,116不处理
|
|
|
+ if (type == NormalChargeConstant.PORT_STATUS) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (gunsStatus == PortStatusConstant.CHARGING_END) {
|
|
|
+ //特殊处理端口状态是7充电已完成(充满),TODO:但是116的端口状态拔枪和充满都是7;103上报是7的话会一只走状态7的处理>就是一只查库看订单状态
|
|
|
+ QueryWrapper<OrderStatus> orderStatusQueryWrapper = new QueryWrapper<>();
|
|
|
+ orderStatusQueryWrapper.eq("device_imei", imei).eq("guns_code", port).orderByDesc("create_time").last("limit 1");
|
|
|
+ OrderStatus one = orderStatusService.getOne(orderStatusQueryWrapper);
|
|
|
+
|
|
|
+ //7状态小于30秒内且订单原因不是远程停充
|
|
|
+ if((System.currentTimeMillis()- one.getCreateTime())<30*1000&&one.getReasonStopCharging()!=TransConstant.APP_REMOTE_STOP){
|
|
|
+ logger.info("启动状态还没变化--->当前7状态不处理");
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ //7状态:充电完成未拔枪会一直上报,只有当订单完成并回复解析订单成功,7状态当空闲状态上报
|
|
|
+ if (one.getTransactionOrderReportingActionStatus()==StatusConstant.TRANSACTION_ORDER_REPORTING_ACTION_STATUS_OK&&one.getTransactionOrderReportingActionStatus()==StatusConstant.TRANSACTION_ORDER_REPLY_STATUS_SUCC){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //如果当前设备的最新订单状态已经是'已经充满'的原因并且订单现在的情况是'充电结束'说明不需要再处理,已经处理过了,
|
|
|
+ if (one.getReasonStopCharging() == TransConstant.SOC_FULL_OF_STOP || one.getNowOrderStatus() == StatusConstant.NOW_ORDER_STATUS_CHARGING_ENDING) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //订单充电中,103端口状态2变7:认为充满.//充满情况,因为可能没拔枪113结束充电通知还没上来;手动发停充;在113中处理交易记录上送
|
|
|
+// DeviceParam deviceParam = new DeviceParam();
|
|
|
+// deviceParam.setDeviceId(imei);
|
|
|
+// deviceParam.setCcid(imei);
|
|
|
+// deviceControlerService.sendPortDetailCmd(deviceParam);
|
|
|
+ deviceControlerService.stopCharge(imei, imei, port);
|
|
|
+ DeviceConnectionMsg deviceConnection = socketHandle.getDeviceConnection(model.getPileCode());
|
|
|
+
|
|
|
+ QueryWrapper<DeviceStatus> deviceStatusQueryWrapper = new QueryWrapper<>();
|
|
|
+ deviceStatusQueryWrapper.eq("device_imei", imei).eq("gun_port", port);
|
|
|
+ DeviceStatus statusServiceOne = deviceStatusService.getOne(deviceStatusQueryWrapper);
|
|
|
+ one.setEndTime(System.currentTimeMillis());
|
|
|
+
|
|
|
+ //后台计费
|
|
|
+ //Map<String, BigDecimal> start = transMoney.compute(port, model, one.getCreateTime(), one.getEndTime(),true);
|
|
|
+ //byte[] encrypt = transactionFlowPushFrame.sendTrans(deviceConnection, one.getTransOrder(), one.getPileCode(), (byte) port, one.getCreateTime(), one.getEndTime(), model, one.getCard(), start, TransConstant.SOC_FULL_OF_STOP);
|
|
|
+ //one.setOriginalText(encrypt);
|
|
|
+ if (one.getReasonStopCharging()==0) {
|
|
|
+ one.setReasonStopCharging(TransConstant.SOC_FULL_OF_STOP);//充满
|
|
|
+ }
|
|
|
+ one.setNowOrderStatus(StatusConstant.NOW_ORDER_STATUS_CHARGING_ENDING);//已结束
|
|
|
+ one.setStopChargingReply(StatusConstant.STOP_CHARGING_REPLY_NO);//记录为停充回复
|
|
|
+ one.setTransactionOrderReportingActionStatus(StatusConstant.TRANSACTION_ORDER_REPORTING_ACTION_STATUS_NO);//未送交易
|
|
|
+ orderStatusService.updateById(one);
|
|
|
+
|
|
|
+ } else if (gunsStatus == PortStatusConstant.FREE) {
|
|
|
+ //特俗处理:校验是不是最新订单是充电中原因没有等等,也就是订单未结束时直接状态成了未插枪状态
|
|
|
+ QueryWrapper<OrderStatus> orderStatusQueryWrapper = new QueryWrapper<>();
|
|
|
+ orderStatusQueryWrapper.eq("device_imei", imei).eq("guns_code", port).orderByDesc("create_time").last("limit 1");
|
|
|
+ OrderStatus one = orderStatusService.getOne(orderStatusQueryWrapper);
|
|
|
+ if (one == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (one.getReasonStopCharging() == 0 && one.getNowOrderStatus() == StatusConstant.NOW_ORDER_STATUS_CHARGING) {
|
|
|
+ //校验通过,说明是直接拔枪了,拔枪设备会主动上报113结束充电通知
|
|
|
+ one.setEndTime(System.currentTimeMillis());
|
|
|
+ //手动停充
|
|
|
+ one.setReasonStopCharging(TransConstant.MANUAL_STOP);
|
|
|
+ one.setNowOrderStatus(StatusConstant.NOW_ORDER_STATUS_CHARGING_ENDING);
|
|
|
+ one.setStopChargingReply(StatusConstant.STOP_CHARGING_REPLY_OK);//已停充
|
|
|
+ orderStatusService.updateById(one);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 1.这里接收到消息就是设备在线;2.对状态进行处理,不同类型消息的枪状态不同进行落库;3.并且状态变化的一个变位上送
|
|
|
+ *
|
|
|
+ * @param imei 设备imei码
|
|
|
+ * @param port 设备port(枪号)
|
|
|
+ * @param gunsStatus 枪状态
|
|
|
+ */
|
|
|
+ private void deviceOnline(String imei, int port, byte gunsStatus, byte insertGunStatus) throws Exception{
|
|
|
+ QueryWrapper<DeviceStatus> deviceStatusQueryWrapper = new QueryWrapper<>();
|
|
|
+ deviceStatusQueryWrapper.eq("device_imei", imei).eq("gun_port", port);
|
|
|
+ DeviceStatus statusServiceOne = deviceStatusService.getOne(deviceStatusQueryWrapper);
|
|
|
+ DeviceStatus statusServiceOneTemp = new DeviceStatus();
|
|
|
+ if (statusServiceOne != null) {
|
|
|
+ BeanUtils.copyProperties(statusServiceOne, statusServiceOneTemp);
|
|
|
+ } else {
|
|
|
+ //禁用的设备不再上线,只看正常设备
|
|
|
+
|
|
|
+// if ("864606063793920".equals(imei)){
|
|
|
+// QueryWrapper<Device> deviceQueryWrapper = new QueryWrapper<>();
|
|
|
+// QueryWrapper<Device> device_imei = deviceQueryWrapper.eq("device_imei", imei);
|
|
|
+// Device a = deviceService.getOne(device_imei);
|
|
|
+// logger.info("a>>"+a.toString());
|
|
|
+// }
|
|
|
+
|
|
|
+ QueryWrapper<Device> deviceQueryWrapper = new QueryWrapper<>();
|
|
|
+ QueryWrapper<Device> device_imei = deviceQueryWrapper.eq("device_imei", imei).eq("disabled", DeviceOnlineStatus.NORMAL);
|
|
|
+ Device one = deviceService.getOne(device_imei);
|
|
|
+ if (one == null) {
|
|
|
+ logger.info("当前设备imei:" + imei + ",没有绑定ykc桩编码!!!!!!!!!!!!!!!!!!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ statusServiceOne = new DeviceStatus();
|
|
|
+ statusServiceOne.setDeviceImei(imei);
|
|
|
+ statusServiceOne.setDeviceSn(one.getDeviceSn());
|
|
|
+ statusServiceOne.setPileCode(one.getPileCode());
|
|
|
+ statusServiceOne.setGunPort((byte) port);
|
|
|
+ statusServiceOne.setCreateTime(System.currentTimeMillis());
|
|
|
+ statusServiceOne.setUpdateTime(System.currentTimeMillis());
|
|
|
+ deviceStatusService.saveOrUpdate(statusServiceOne);
|
|
|
+ }
|
|
|
+ QueryWrapper<Device> deviceQueryWrapper = new QueryWrapper<>();
|
|
|
+ deviceQueryWrapper.eq("pile_code", statusServiceOne.getPileCode()).eq("disabled", DeviceOnlineStatus.NORMAL);
|
|
|
+ Device device = deviceService.getOne(deviceQueryWrapper);
|
|
|
+
|
|
|
+ if (!socketHandle.existDeviceConnection(statusServiceOne.getPileCode())) {
|
|
|
+ try {
|
|
|
+
|
|
|
+ socketHandle.addDeviceConnection(device.getIp(),device.getPort(),statusServiceOne.getPileCode(), statusServiceOne.getDeviceImei(), statusServiceOne.getDeviceSn());
|
|
|
+ loginFrame.loginMsgSend(socketHandle.getDeviceConnection(statusServiceOne.getPileCode()), device);
|
|
|
+ //从新登录可能造成通讯上的问题,这里不在往下进行状态操作
|
|
|
+ return;
|
|
|
+ } catch (IOException e) {
|
|
|
+ logger.info("device:" + statusServiceOne.getDeviceSn() + " open socket Exception!!!");
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //存在连接校验socket连接是否正常
|
|
|
+ DeviceConnectionMsg deviceConnection = socketHandle.getDeviceConnection(statusServiceOne.getPileCode());
|
|
|
+ if (!deviceConnection.getSocket().isConnected()) {
|
|
|
+ //不正常,移除再连接
|
|
|
+ socketHandle.removeDeviceConnection(statusServiceOne.getPileCode());
|
|
|
+ try {
|
|
|
+ socketHandle.addDeviceConnection(device.getIp(),device.getPort(),statusServiceOne.getPileCode(), statusServiceOne.getDeviceImei(), statusServiceOne.getDeviceSn());
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ logger.info("设备原状态>>>" + statusServiceOneTemp.toString());
|
|
|
+ statusServiceOne.setGunStatus(gunsStatus);
|
|
|
+ statusServiceOne.setInsertGunStatus(insertGunStatus);
|
|
|
+ statusServiceOne.setOnlineStatus(DeviceOnlineStatus.ONLINE);
|
|
|
+ statusServiceOne.setUpdateTime(System.currentTimeMillis());
|
|
|
+ deviceStatusService.updateById(statusServiceOne);
|
|
|
+ logger.info("设备状态持久化>>>" + statusServiceOne.toString());
|
|
|
+
|
|
|
+ //1.redis也更新掉
|
|
|
+
|
|
|
+ if (port == 1) {
|
|
|
+ if (redisCache.hasKey(RedisConstant.ONLINE_DEVICE_ONE)) {
|
|
|
+ DeviceStatus ds = redisCache.getCacheMapValue(RedisConstant.ONLINE_DEVICE_ONE, statusServiceOne.getPileCode());
|
|
|
+ if (ds != null) {
|
|
|
+ redisCache.deleteCacheMapValue(RedisConstant.ONLINE_DEVICE_ONE, statusServiceOne.getPileCode());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (port == 2) {
|
|
|
+ if (redisCache.hasKey(RedisConstant.ONLINE_DEVICE_TWO)) {
|
|
|
+ DeviceStatus ds = redisCache.getCacheMapValue(RedisConstant.ONLINE_DEVICE_TWO, statusServiceOne.getPileCode());
|
|
|
+ if (ds != null) {
|
|
|
+ redisCache.deleteCacheMapValue(RedisConstant.ONLINE_DEVICE_TWO, statusServiceOne.getPileCode());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ redisCache.setCacheMapValue(port == 1 ? RedisConstant.ONLINE_DEVICE_ONE : RedisConstant.ONLINE_DEVICE_TWO, statusServiceOne.getPileCode(), statusServiceOne);
|
|
|
+ redisCache.expire(port == 1 ? RedisConstant.ONLINE_DEVICE_ONE : RedisConstant.ONLINE_DEVICE_TWO, 60 * 1001 * 20, TimeUnit.MILLISECONDS);
|
|
|
+
|
|
|
+ //2.状态变位上送,状态变化需要上送一个实时状态帧;前提是已经在云快充登录成功
|
|
|
+ if (statusServiceOneTemp.getGunStatus() != gunsStatus || statusServiceOneTemp.getInsertGunStatus() != insertGunStatus) {
|
|
|
+ if (!socketHandle.existDeviceConnection(statusServiceOne.getPileCode())) {
|
|
|
+ try {
|
|
|
+ socketHandle.addDeviceConnection(device.getIp(),device.getPort(),statusServiceOne.getPileCode(), statusServiceOne.getDeviceImei(), statusServiceOne.getDeviceSn());
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ DeviceConnectionMsg deviceConnectionMsg = socketHandle.getDeviceConnection(statusServiceOne.getPileCode());
|
|
|
+ if (deviceConnectionMsg.getLoginStatus() == 1) { //设备登录成功才会有其他的操作,登录没成功无法变位上送
|
|
|
+ QueryWrapper<OrderStatus> orderStatusQueryWrapper = new QueryWrapper<>();
|
|
|
+ orderStatusQueryWrapper.eq("device_imei", imei).eq("guns_code", port).orderByDesc("create_time").last("limit 1");
|
|
|
+ OrderStatus one = orderStatusService.getOne(orderStatusQueryWrapper);
|
|
|
+
|
|
|
+ if (one==null){
|
|
|
+ logger.info("orderStatus is null ,status ↑↑↑↑");
|
|
|
+ realTimeStatusPushFrame.deviceStatusPush(deviceConnectionMsg, FrameDataSplicing.transactionNum(null,0), statusServiceOne.getPileCode(), (byte) port, gunsStatus, insertGunStatus, 0, 0, zero, zero, 0);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //判断区分是因为充电中流水和待机状态流水号不同
|
|
|
+ if (gunsStatus == StatusConstant.CHARGING) {
|
|
|
+ //这里的变位是变为充电中需要注意交易流水号的变更问题,流水号在云快充启充指令时获得并已经持久化到数据库中
|
|
|
+ byte[] transactionNum = one.getTransOrder();
|
|
|
+
|
|
|
+ if (one.getChargingInitStatus() == StatusConstant.CHARGING_INIT_STATUS_NO) {
|
|
|
+ logger.info("变位为充电中且当前订单还没首次上报过初始状态:" + DataConversion.bytesToHexString(transactionNum));
|
|
|
+ realTimeStatusPushFrame.deviceStatusPush(deviceConnectionMsg, transactionNum, statusServiceOneTemp.getPileCode(), (byte) port, gunsStatus, insertGunStatus, 0, 0, zero, zero, 0);
|
|
|
+ }
|
|
|
+ //这里上报开始充电初始化状态并记录已经上报首次状态
|
|
|
+ one.setNowOrderStatus(StatusConstant.NOW_ORDER_STATUS_CHARGING);
|
|
|
+ one.setChargingInitStatus(StatusConstant.CHARGING_INIT_STATUS_OK);
|
|
|
+ orderStatusService.updateById(one);
|
|
|
+ } else {
|
|
|
+ logger.info(statusServiceOne.getPileCode() + ":除了充电变位的其他状态>>>>>>" + gunsStatus);
|
|
|
+ //这里的状态变位是除了充电中以外的情况
|
|
|
+ byte[] transactionNum = FrameDataSplicing.transactionNum(statusServiceOneTemp.getPileCode(), deviceConnectionMsg.getMessageCount());
|
|
|
+ if (gunsStatus == PortStatusConstant.EMERGENCY_STOP) {
|
|
|
+ // 急停后库里记录的是急停状态,但是上报的时候需上报云快充一次故障状态;所以临时为故障上报
|
|
|
+ gunsStatus = StatusConstant.FAULT;
|
|
|
+ logger.info(statusServiceOne.getPileCode() + ":状态变位为急停时需要一次故障状态:" + gunsStatus);
|
|
|
+ } else if (gunsStatus == PortStatusConstant.CHARGING_END&&one.getReasonStopCharging()==0) {
|
|
|
+ //状态是7充电完成
|
|
|
+ gunsStatus = StatusConstant.FREE;
|
|
|
+ }else if (one.getReasonStopCharging()==0){
|
|
|
+ one.setReasonStopCharging(TransConstant.MANUAL_STOP);
|
|
|
+ }
|
|
|
+ //状态未知按手动停充
|
|
|
+
|
|
|
+// 如果断网后在断网时进行的停充,那么现在情况->1.设备状态离线2.订单记录还是 : 充电中0,没有停止指令上送0,交易记录也没有上送0,停止原因也是0,结束时间是null
|
|
|
+ //TODO:停止充电时间怎么算:目前考虑的是检测到离线的时间就说device中的updateTime来当结束充电时间
|
|
|
+
|
|
|
+ String transOrder = "";
|
|
|
+ if (redisCache.hasKey(RedisConstant.NO_INSERT_GUN_YKC + statusServiceOneTemp.getPileCode())) {
|
|
|
+ //未插枪启充的操作会保存订单,但是订单号不是因为断网中停充造成的订单结束原因是0,所以redis有当前设备的订单值,就不是结束充电
|
|
|
+ transOrder = redisCache.getCacheObject(RedisConstant.NO_INSERT_GUN_YKC + statusServiceOneTemp.getPileCode());
|
|
|
+ }
|
|
|
+ //急停状态下不管是断网时急停还是直接按的急停都按急停处理,不按手动处理;
|
|
|
+ //TODO:急停情况已经上报交易,其他从充电变成非已充电全部上报交易记录
|
|
|
+ //原枪状态是充电中,现在不是根据状态上报
|
|
|
+ logger.info("原本状态>>>>>>>>>>>>>>>>>"+statusServiceOneTemp.toString());
|
|
|
+ logger.info("当前状态状态>>>>>>>>>>>>>>>>>"+statusServiceOne.toString());
|
|
|
+ if (statusServiceOneTemp.getGunStatus()==StatusConstant.CHARGING&&statusServiceOne.getGunStatus()!=StatusConstant.CHARGING){
|
|
|
+ QueryWrapper<BillingModel> billingModelQueryWrapper = new QueryWrapper<>();
|
|
|
+ billingModelQueryWrapper.eq("device_imei", imei);
|
|
|
+ BillingModel model = billingModelService.getOne(billingModelQueryWrapper);
|
|
|
+
|
|
|
+ byte[] encrypt = new byte[0];
|
|
|
+ Long endTime=System.currentTimeMillis();
|
|
|
+ if (port == 1) {
|
|
|
+ logger.info("订单状态orderStatus>>"+one.toString());
|
|
|
+ Map<String, BigDecimal> map = transMoney.compute(1, model, one.getCreateTime(), endTime + 3 * 60 * 1000, true);
|
|
|
+ //logger.info("断网中停充>>>上报交易记录>>>");
|
|
|
+ encrypt = transactionFlowPushFrame.sendTrans(deviceConnectionMsg, one.getTransOrder(), statusServiceOne.getPileCode(), (byte) 1, one.getCreateTime(), statusServiceOneTemp.getUpdateTime() + 3 * 60 * 1000, model, one.getCard(), map, one.getReasonStopCharging());
|
|
|
+ } else if (port == 2) {
|
|
|
+
|
|
|
+ Map<String, BigDecimal> map = transMoney.compute(2, model, one.getCreateTime(), endTime + 3 * 60 * 1000, true);
|
|
|
+ BigDecimal elec = map.get("elec");
|
|
|
+ BigDecimal money = map.get("money");
|
|
|
+ encrypt = transactionFlowPushFrame.sendTrans(deviceConnectionMsg, one.getTransOrder(), statusServiceOne.getPileCode(), (byte) 2, one.getCreateTime(), statusServiceOneTemp.getUpdateTime() + 3 * 60 * 1000, model, one.getCard(), map, statusServiceOneTemp.getFlage() == 2 ? TransConstant.CHARGING_STATION_POWER_OUTAGE : TransConstant.EMERGENCY_STOP_EXCEPTION_STOP);
|
|
|
+ }
|
|
|
+ /* if (port == 1) {
|
|
|
+ Map<String, BigDecimal> map = transMoney.compute(1, model, one.getCreateTime(), endTime + 3 * 60 * 1000, true);
|
|
|
+ //logger.info("断网中停充>>>上报交易记录>>>");
|
|
|
+ encrypt = transactionFlowPushFrame.sendTrans(deviceConnectionMsg, one.getTransOrder(), statusServiceOne.getPileCode(), (byte) 1, one.getCreateTime(), statusServiceOneTemp.getUpdateTime() + 3 * 60 * 1000, model, one.getCard(), map, statusServiceOneTemp.getFlage() == 2 ? TransConstant.CHARGING_STATION_POWER_OUTAGE : TransConstant.EMERGENCY_STOP_EXCEPTION_STOP);
|
|
|
+ } else if (port == 2) {
|
|
|
+
|
|
|
+ Map<String, BigDecimal> map = transMoney.compute(2, model, one.getCreateTime(), endTime + 3 * 60 * 1000, true);
|
|
|
+ BigDecimal elec = map.get("elec");
|
|
|
+ BigDecimal money = map.get("money");
|
|
|
+ encrypt = transactionFlowPushFrame.sendTrans(deviceConnectionMsg, one.getTransOrder(), statusServiceOne.getPileCode(), (byte) 2, one.getCreateTime(), statusServiceOneTemp.getUpdateTime() + 3 * 60 * 1000, model, one.getCard(), map, statusServiceOneTemp.getFlage() == 2 ? TransConstant.CHARGING_STATION_POWER_OUTAGE : TransConstant.EMERGENCY_STOP_EXCEPTION_STOP);
|
|
|
+ }*/
|
|
|
+ one.setEndTime(endTime+ 3 * 60 * 1000);
|
|
|
+ //手动停充
|
|
|
+ one.setOriginalText(encrypt);
|
|
|
+ //one.setReasonStopCharging(one);
|
|
|
+ one.setNowOrderStatus(StatusConstant.NOW_ORDER_STATUS_CHARGING_ENDING);
|
|
|
+ one.setStopChargingReply(StatusConstant.STOP_CHARGING_REPLY_OK);//停止指令回复云快充(模拟的)
|
|
|
+ one.setTransactionOrderReportingActionStatus(StatusConstant.TRANSACTION_ORDER_REPORTING_ACTION_STATUS_OK);
|
|
|
+ orderStatusService.updateById(one);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* if (statusServiceOne.getGunStatus() != PortStatusConstant.EMERGENCY_STOP && one != null && !(transOrder.equals(DataConversion.bytesToHexString(one.getTransOrder()))) && one.getReasonStopCharging() == 0 && one.getNowOrderStatus() == StatusConstant.NOW_ORDER_STATUS_CHARGING && one.getStopChargingReply() == StatusConstant.STOP_CHARGING_REPLY_NO && one.getTransactionOrderReportingActionStatus() == StatusConstant.TRANSACTION_ORDER_REPORTING_ACTION_STATUS_NO ) {
|
|
|
+ //这里需要查下103因为断网中停充可能103没有上来
|
|
|
+ DeviceParam deviceParam = new DeviceParam();
|
|
|
+ deviceParam.setDeviceId(imei);
|
|
|
+ deviceParam.setCcid(imei);
|
|
|
+ deviceControlerService.sendPortDetailCmd(deviceParam);
|
|
|
+ *//*QueryWrapper<BillingModel> billingModelQueryWrapper = new QueryWrapper<>();
|
|
|
+ billingModelQueryWrapper.eq("device_imei", imei);
|
|
|
+ BillingModel model = billingModelService.getOne(billingModelQueryWrapper);
|
|
|
+ byte[] encrypt = new byte[0];
|
|
|
+ if (port == 1) {
|
|
|
+ Map<String, BigDecimal> map = transMoney.compute(1, model, one.getCreateTime(), statusServiceOneTemp.getUpdateTime() + 3 * 60 * 1000, true);
|
|
|
+ //logger.info("断网中停充>>>上报交易记录>>>");
|
|
|
+ encrypt = transactionFlowPushFrame.sendTrans(deviceConnectionMsg, one.getTransOrder(), statusServiceOne.getPileCode(), (byte) 1, one.getCreateTime(), statusServiceOneTemp.getUpdateTime() + 3 * 60 * 1000, model, one.getCard(), map, statusServiceOneTemp.getFlage() == 2 ? TransConstant.CHARGING_STATION_POWER_OUTAGE : TransConstant.EMERGENCY_STOP_EXCEPTION_STOP);
|
|
|
+ } else if (port == 2) {
|
|
|
+
|
|
|
+ Map<String, BigDecimal> map = transMoney.compute(2, model, one.getCreateTime(), statusServiceOneTemp.getUpdateTime() + 3 * 60 * 1000, true);
|
|
|
+ BigDecimal elec = map.get("elec");
|
|
|
+ BigDecimal money = map.get("money");
|
|
|
+ encrypt = transactionFlowPushFrame.sendTrans(deviceConnectionMsg, one.getTransOrder(), statusServiceOne.getPileCode(), (byte) 2, one.getCreateTime(), statusServiceOneTemp.getUpdateTime() + 3 * 60 * 1000, model, one.getCard(), map, statusServiceOneTemp.getFlage() == 2 ? TransConstant.CHARGING_STATION_POWER_OUTAGE : TransConstant.EMERGENCY_STOP_EXCEPTION_STOP);
|
|
|
+ }*//*
|
|
|
+ //订单断网停充上送交易订单
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ */ //插枪状态变化需要看是不是有启充时没插枪的情况
|
|
|
+ if (insertGunStatus == StatusConstant.INSERT_GUNS_YES && gunsStatus == StatusConstant.FREE) {
|
|
|
+ if (redisCache.hasKey(RedisConstant.NO_INSERT_GUN_YKC + statusServiceOneTemp.getPileCode())) {
|
|
|
+ //有择发启充设备,然后移除掉redis
|
|
|
+ logger.info(statusServiceOne.getPileCode() + ":云快充启动时未插枪>检测到插枪启动>>>订单>>" + DataConversion.bytesToHexString(one.getTransOrder()));
|
|
|
+ deviceControlerService.startCharge(statusServiceOneTemp.getDeviceImei(), statusServiceOneTemp.getDeviceImei(), port, 0);
|
|
|
+ charngingPushFrame.startStatus(deviceConnectionMsg, one.getTransOrder(), port, 0x01, 0x00);
|
|
|
+ redisCache.deleteObject(RedisConstant.NO_INSERT_GUN_YKC + statusServiceOneTemp.getPileCode());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ logger.info(statusServiceOne.getPileCode() + ":设备变位状态上送枪状态>>>" + gunsStatus + ";插枪状态:" + insertGunStatus);
|
|
|
+ realTimeStatusPushFrame.deviceStatusPush(deviceConnectionMsg, transactionNum, statusServiceOne.getPileCode(), (byte) port, gunsStatus, insertGunStatus, 0, 0, zero, zero, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|