| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800 |
- 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.tmzn.devicelinkykc.constant.Constant;
- import com.tmzn.devicelinkykc.constant.DeviceOnlineStatus;
- import com.tmzn.devicelinkykc.constant.PortStatusConstant;
- import com.tmzn.devicelinkykc.constant.RedisConstant;
- 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.openfeign.transdata.RpcResult;
- 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.apache.logging.log4j.util.Strings;
- 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;
- /**
- * @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();
- }
- String imei = jsonObject.getString("imei");
- if (Strings.isEmpty(imei)) {
- return;
- }
- String pileCode = "";
- try {
- pileCode = redisCache.getCacheMapValue(RedisConstant.DEVICE_IMEI_PILE_MAP, imei);
- if (Strings.isEmpty(pileCode)) {
- return;
- }
- } catch (Exception e) {
- return;
- }
- logger.info("{},msg>>>" + msg, imei);
- //设备状态更新,true:没有type不是设备上送类型不往云快充处理 false:需要根据设备消息类型往下处理是不是需要上报云快充
- try {
- handleDeviceMsg(jsonObject, pileCode);
- } catch (Exception e) {
- logger.error("处理消息失败{},{}", imei, e.getMessage());
- e.printStackTrace();
- }
- }
- public void testMsg(String msg) throws Exception {
- logger.info("testmsg>>>" + msg);
- JSONObject jsonObject = null;
- jsonObject = JSONObject.parseObject(msg);
- String imei = jsonObject.getString("imei");
- try {
- String pileCode = redisCache.getCacheMapValue(RedisConstant.DEVICE_IMEI_PILE_MAP, imei);
- if (Strings.isEmpty(pileCode)) {
- logger.info("非云快充设备");
- return;
- }
- handleDeviceMsg(jsonObject, pileCode);
- } catch (Exception e) {
- return;
- }
- //设备状态更新,true:没有type不是设备上送类型不往云快充处理 false:需要根据设备消息类型往下处理是不是需要上报云快充
- }
- 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;
- }
- }
- //处理离线消息
- //查找所有端口状态置为下线 并推送状态给云快充
- private void handleOffline(String imei) {
- QueryWrapper<DeviceStatus> deviceStatusQueryWrapper = new QueryWrapper<>();
- deviceStatusQueryWrapper.eq("device_imei", imei);
- List<DeviceStatus> list = deviceStatusService.list(deviceStatusQueryWrapper);
- if (!list.isEmpty()) {
- 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);
- }
- }
- }
- }
- private void checkNoPowerAutoStop(int power, String imei, int portId) {
- try {
- String hkey = imei + "_" + portId;
- Integer lastPower0Times = 0;
- if (power > 0) {
- } else {
- lastPower0Times = redisCache.getCacheMapValue(RedisConstant.POWER_ZERO_TIMES, hkey);
- if (lastPower0Times == null) {
- lastPower0Times = 0;
- }
- lastPower0Times = lastPower0Times + 1;
- }
- redisCache.setCacheMapValue(RedisConstant.POWER_ZERO_TIMES, hkey, lastPower0Times);
- if (lastPower0Times < 5) {
- return;
- }
- //查找订单开始时间 如果开始时间过过2分钟 且连续power为0 就需要停止充电
- QueryWrapper<OrderStatus> orderStatusQueryWrapper = new QueryWrapper<>();
- orderStatusQueryWrapper.eq("device_imei", imei).eq("guns_code", portId).orderByDesc("create_time").last("limit 1");
- OrderStatus one = orderStatusService.getOne(orderStatusQueryWrapper);
- if (one.getNowOrderStatus() != StatusConstant.NOW_ORDER_STATUS_CHARGING) {
- return;
- }
- if ((System.currentTimeMillis() - one.getCreateTime()) < 120 * 1000) {
- return;
- }
- //连续3次功率0 就要停止充电
- RpcResult rpcResult = deviceControlerService.stopCharge(imei, imei, (int) portId);
- logger.info("{}-{}触发无功率自停{}", imei, portId, lastPower0Times);
- } catch (Exception e) {
- logger.error("无功率检测异常{}", e.getMessage());
- e.printStackTrace();
- }
- }
- public boolean checkConnection(String pileCode, String imei) throws IOException {
- boolean needLogin = false;
- if (!socketHandle.existDeviceConnection(pileCode)) {
- needLogin = true;
- } else {
- DeviceConnectionMsg deviceConnection = socketHandle.getDeviceConnection(pileCode);
- if (!deviceConnection.getSocket().isConnected()) {
- socketHandle.removeDeviceConnection(pileCode);
- needLogin = true;
- }
- }
- if (!needLogin) {
- return true;
- }
- logger.info("桩上线{}", imei);
- QueryWrapper<Device> deviceQueryWrapper = new QueryWrapper<>();
- deviceQueryWrapper.eq("pile_code", pileCode).eq("disabled", DeviceOnlineStatus.NORMAL);
- Device device = deviceService.getOne(deviceQueryWrapper);
- if (device == null) {
- logger.info("{}已禁用{}", imei, pileCode);
- return false;
- }
- socketHandle.addDeviceConnection(device.getIp(), device.getPort(), device.getPileCode(), device.getDeviceImei(), device.getDeviceSn(), device.getCommProtocolVer());
- loginFrame.loginMsgSend(socketHandle.getDeviceConnection(device.getPileCode()), device);
- return false;
- }
- /**
- * 设备状态按照设备上报和设备心跳上送时间校验修改,这里就必须更新状态的修改时间;通过定时任务判断在线设备接收心跳包超10分钟改为离线
- *
- * @param jsonObject
- */
- private void handleDeviceMsg(JSONObject jsonObject, String pileCode) throws Exception {
- String imei = jsonObject.getString("imei");
- Integer cmd = jsonObject.getInteger("cmd");
- if (!jsonObject.containsKey("type")) {
- //TODO:离线判断:设备上报+?设备心跳时间校验?
- //没有type但是cmd指令是离线时37896=========
- if (cmd == 37896) {
- //处理离线消息
- handleOffline(imei);
- }
- return;
- }
- try {
- checkConnection(pileCode, imei);
- } catch (Exception e) {
- logger.info("桩{}连接异常", imei);
- }
- Integer type = jsonObject.getInteger("type");
- if (!NormalChargeConstant.CMD_SET_MAINBOARD.equals(cmd)) {
- // logger.error("不支持的命令");
- return;
- }
- //端口状态
- if (NormalChargeConstant.KEY_PORT_DETAIL.equals(type)) {
- handle103(jsonObject, imei, type);
- return;
- }
- if (NormalChargeConstant.PORT_STATUS.equals(type)) {
- //116端口详情也会变化
- JSONArray data = jsonObject.getJSONArray("data");
- checkPort(data.getInteger(4), data.getInteger(3), imei, type);
- return;
- }
- //指定端口状态
- if (NormalChargeConstant.KEY_PORT_STATUS.equals(type)) {
- handle101(jsonObject, imei, type);
- return;
- }
- //104消息启动充电
- if (NormalChargeConstant.KEY_STARTCHARGE.equals(type)) {
- handle104(jsonObject, imei);
- return;
- }
- //结束充电
- if (NormalChargeConstant.KEY_END_NOTICE.equals(type)) {
- handle113(jsonObject, imei);
- return;
- }
- //TODO:设备状态的修改这里进行监听变化 ,??
- // 1.设备消息cmd:75960设备上报消息是的命令,只要设备报的不是离线当做设备在线
- // 2.设备上报指令后根据type类型来分类处理消息包括:设备设为在线 是否插枪状态 枪状态(端口状态)
- if (NormalChargeConstant.EMERGENCY_STOP_CHARGING.equals(type)) {
- handleEmergency(jsonObject, imei);
- return;
- }
- if (NormalChargeConstant.REPORT_PORT_STATUS.equals(type)) {
- //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);
- }
- }
- }
- //生产上根本进不来 不考虑 临时调试ykc上报急停状态
- private void handleEmergency(JSONObject jsonObject, String imei) throws Exception {
- //急停停充
- 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) {
- logger.info(statusServiceOne.getPileCode() + ":急停停充>>>上报交易记录>>>");
- byte[] encrypt = new byte[0];
- if (port == 1) {
- //急停停充:急停状态下:1.向设备发起结束充电,结算交易订单(交给结束充电处理;但是要考虑是急停的原因),2.上报的充电结束的订单式
- Map<String, BigDecimal> map = transMoney.compute(1, model, statusServiceOne.getCreateTime(), statusServiceOne.getEndTime());
- 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:这里还是模拟数据上报
- Map<String, BigDecimal> map = transMoney.compute(2, model, statusServiceOne.getCreateTime(), statusServiceOne.getEndTime());
- //模拟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);
- }
- }
- //启动充电
- private void handle104(JSONObject jsonObject, String imei) {
- //开启充电设备上报结果
- JSONObject data = jsonObject.getJSONObject("real_data");
- Integer result = data.getInteger("result");
- Integer port = data.getInteger("port");
- 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);
- logger.info("上报启动充电成功{},{}", statusServiceOne.getId(), statusServiceOne.getPileCode());
- } else {
- //启机不成功,根据设备状态判断,并且要结束充电并上报订单
- String cacheKey;
- if (port == 1) {
- cacheKey = RedisConstant.ONLINE_DEVICE_ONE;
- } else {
- cacheKey = RedisConstant.ONLINE_DEVICE_TWO;
- }
- if (redisCache.hasKey(cacheKey)) {
- DeviceStatus oneStatus = redisCache.getCacheMapValue(cacheKey, 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);
- logger.info("上报启动充电失败{},{}", statusServiceOne.getId(), statusServiceOne.getPileCode());
- }
- }
- new Thread(() -> {
- try {
- Thread.sleep(4000); // 延迟 5 秒
- DeviceParam dataParam = new DeviceParam();
- dataParam.setDeviceId(imei);
- dataParam.setCcid(imei);
- deviceControlerService.sendPortDetailCmd(dataParam);
- logger.info(statusServiceOne.getPileCode() + ":延迟主动下发103消息" + imei);
- } catch (Exception e) {
- logger.info(statusServiceOne.getPileCode() + ":延迟主动下发103消息异常" + e.getMessage() + imei);
- }
- }).start();
- }
- //单个端口状态
- private void handle101(JSONObject jsonObject, String imei, int type) {
- try {
- //状态查询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);
- }
- } catch (Exception e) {
- logger.info("处理101失败{}", imei);
- }
- }
- private void handle103(JSONObject jsonObject, String imei, int type) throws Exception {
- //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");
- //功率为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, 30, TimeUnit.MINUTES);
- if (port_first_status != null) {
- checkPort(port_first_status, 1, imei, type);
- if (port_first_status == PortStatusConstant.CHARGING) {
- Integer power = data.getInteger("power");
- checkNoPowerAutoStop(power, imei, 1);
- }
- }
- if (port_second_status != null) {
- checkPort(port_second_status, 2, imei, type);
- if (port_second_status == PortStatusConstant.CHARGING) {
- Integer power = data.getInteger("power_1");
- checkNoPowerAutoStop(power, imei, 2);
- }
- }
- }
- //处理停止充电情况
- private void handle113(JSONObject jsonObject, String imei) {
- //停止充电通知触发情况:1.急停,收到停充时主动要去发停充,所以这里不能处理急停的交易订单;2.手动停充,正常的远程停止指令
- // 1.设备已经在接收到云快充指令的时候进行了停充操作,2.结算订单,上报云快充停止回复
- try {
- JSONObject data = jsonObject.getJSONObject("real_data");
- logger.info("{}接收到设备上送113停止充电msg>>" + jsonObject.toString(), imei);
- 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 (statusServiceOne == null) {
- logger.info("没有待处理订单{}", imei);
- deviceControlerService.sendImeiDetail(imei);
- return;
- }
- if (statusServiceOne.getTransactionOrderReplyStatus() == StatusConstant.TRANSACTION_ORDER_REPLY_STATUS_SUCC) {
- logger.info("订单状态已上报成功{},id:{}", imei, statusServiceOne.getId());
- deviceControlerService.sendImeiDetail(imei);
- return;
- }
- //如果是用户手动停止充电 则不处理状态
- if (statusServiceOne.getReasonStopCharging() == TransConstant.APP_REMOTE_STOP) {
- logger.info(statusServiceOne.getPileCode() + ":云快充>>>>>>远程停充>>>>");
- } else {
- if(statusServiceOne.getReasonStopCharging()==0){
- logger.info(statusServiceOne.getPileCode() + ":充满主动>>>>>>停充>>>>");
- }else{
- //不处理急停
- if (reson == 0x01) {
- logger.info(statusServiceOne.getPileCode() + ":用户主动停充>>>>>>停充>>>>");
- statusServiceOne.setReasonStopCharging(TransConstant.APP_REMOTE_STOP);
- } else if (reson == 0x00) {
- logger.info(statusServiceOne.getPileCode() + ":设备余额不足>>>>>>停充>>>>");
- statusServiceOne.setReasonStopCharging(TransConstant.INSUFFICIENT_BALANCE_EXCEPTION_STOP);
- } else if (reson == 0x03) {
- logger.info(statusServiceOne.getPileCode() + ":设备充电充满>>>>>>停充>>>>");
- statusServiceOne.setReasonStopCharging(TransConstant.SOC_FULL_OF_STOP);
- } else {
- logger.info(statusServiceOne.getPileCode() + ":设备充电停止>>>>其他>>>");
- statusServiceOne.setReasonStopCharging(TransConstant.OTHER_STOP);
- }
- }
- }
- //设置订单已停止充电和结束时间
- statusServiceOne.setEndTime(System.currentTimeMillis());
- statusServiceOne.setNowOrderStatus(StatusConstant.NOW_ORDER_STATUS_CHARGING_ENDING);
- DeviceConnectionMsg deviceConnection = socketHandle.getDeviceConnection(statusServiceOne.getPileCode());
- if (deviceConnection == null || deviceConnection.getLoginStatus() != 1) {
- //未上报
- statusServiceOne.setTransactionOrderReportingActionStatus(StatusConstant.TRANSACTION_ORDER_REPORTING_ACTION_STATUS_NO);
- logger.info("socket 未连接 需要重新上报异常上报{}", statusServiceOne.getPileCode());
- orderStatusService.updateById(statusServiceOne);
- return;
- }
- byte[] encrypt = new byte[0];
- //查询计费模板
- QueryWrapper<BillingModel> billingModelQueryWrapper = new QueryWrapper<>();
- billingModelQueryWrapper.eq("device_imei", imei);
- BillingModel model = billingModelService.getOne(billingModelQueryWrapper);
- Map<String, BigDecimal> map = transMoney.compute(port, model, statusServiceOne.getCreateTime(), statusServiceOne.getEndTime());
- logger.info(statusServiceOne.getPileCode() + "计算电费" + DataConversion.bytesToHexString(statusServiceOne.getTransOrder()));
- encrypt = transactionFlowPushFrame.sendTrans(deviceConnection, statusServiceOne.getTransOrder(), statusServiceOne.getPileCode(), statusServiceOne.getGunsCode(), statusServiceOne.getCreateTime(), statusServiceOne.getEndTime(), model, statusServiceOne.getCard(), map, statusServiceOne.getReasonStopCharging());
- if (encrypt == null || encrypt.length <= 0) {
- logger.info("订单上送消息异常 需要重新上报{}", statusServiceOne.getPileCode());
- orderStatusService.updateById(statusServiceOne);
- return;
- } else {
- logger.info("订单上送成功{}", statusServiceOne.getPileCode());
- statusServiceOne.setTransactionOrderReportingActionStatus(StatusConstant.TRANSACTION_ORDER_REPORTING_ACTION_STATUS_OK);
- statusServiceOne.setOriginalText(encrypt);
- }
- boolean res = charngingPushFrame.endStatus(deviceConnection, port, 0x01, 0x00);
- if (res) {
- //更新远程停止充电
- logger.info("停止充电回复成功{}", imei);
- statusServiceOne.setStopChargingReply(StatusConstant.STOP_CHARGING_REPLY_OK);
- } else {
- logger.info("停止充电回复失败{}", imei);
- }
- orderStatusService.updateById(statusServiceOne);
- // //获取一设备状态
- // DeviceParam dataParam = new DeviceParam();
- // dataParam.setDeviceId(imei);
- // dataParam.setCcid(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);
- deviceControlerService.sendImeiDetail(deviceConnection.getImei());
- } catch (Exception e) {
- logger.info("{}处理113消息异常{}", imei, e.getMessage());
- // 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();
- }
- }
- /**
- * 设备端口状态转成云快充识别状态
- *
- * @param portStatus
- * @param port
- * @param imei
- */
- private void checkPort(Integer portStatus, int port, String imei, int type) throws Exception {
- if (portStatus.equals(PortStatusConstant.FREE)) {
- //处理特殊情况之后还要看枪状态变位上送
- deviceOnline(portStatus, imei, port, StatusConstant.FREE, StatusConstant.INSERT_GUNS_NO);
- return;
- }
- if (portStatus.equals(PortStatusConstant.CHARGING)) {
- deviceOnline(portStatus, imei, port, StatusConstant.CHARGING, StatusConstant.INSERT_GUNS_YES);
- return;
- }
- if (portStatus.equals(PortStatusConstant.DISABLED) || portStatus.equals(PortStatusConstant.FAULT)) {
- //禁用或故障上报云快充为故障信息
- deviceOnline(portStatus, imei, port, StatusConstant.FAULT, StatusConstant.NO);
- return;
- }
- if (portStatus.equals(PortStatusConstant.INSERT_GUN) || portStatus.equals(PortStatusConstant.BOOKED)) {
- deviceOnline(portStatus, imei, port, StatusConstant.FREE, StatusConstant.INSERT_GUNS_YES);
- return;
- }
- if (portStatus.equals(PortStatusConstant.CHARGING_END)) {
- //7状态的时候 充满停止以后 认为未插枪 不允许充电 因为启动不了,必须要重新拔枪
- deviceOnline(portStatus, imei, port, (byte) StatusConstant.FREE, StatusConstant.INSERT_GUNS_NO);
- return;
- }
- if (portStatus.equals(PortStatusConstant.EMERGENCY_STOP)) {
- //急停中按要求需要上报空闲状态;急停保存原始状态
- deviceOnline(portStatus, imei, port, (byte) PortStatusConstant.EMERGENCY_STOP, StatusConstant.INSERT_GUNS_NO);
- }
- }
- /**
- * 1.这里接收到消息就是设备在线;2.对状态进行处理,不同类型消息的枪状态不同进行落库;3.并且状态变化的一个变位上送
- * 枪充满会变成状7 然后必须要拔了再插 才能启动充电
- * 但是拔了再插 会短暂的从1 变成5 所以在判断空闲的时候 要加上订单60秒的变位限制 6如果有订单60秒后才关闭
- * @param imei 设备imei码
- * @param port 设备port(枪号)
- * @param gunsStatus 枪状态
- */
- private void deviceOnline(int portStatus, 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 && insertGunStatus == StatusConstant.INSERT_GUNS_YES){
- String waitingKey = RedisConstant.WAITING_INSERT_GUN+":"+statusServiceOne.getPileCode()+"_"+statusServiceOne.getGunPort();
- if (redisCache.hasKey(waitingKey)) {
- //未插枪启充的操作会保存订单,但是订单号不是因为断网中停充造成的订单结束原因是0,所以redis有当前设备的订单值,就不是结束充电
- int waitingId = redisCache.getCacheObject(waitingKey);
- //启动充电
- QueryWrapper<OrderStatus> orderStatusQueryWrapper = new QueryWrapper<>();
- orderStatusQueryWrapper.eq("device_imei", imei).eq("guns_code", port).orderByDesc("create_time").last("limit 1");
- OrderStatus waitingOrder = orderStatusService.getOne(orderStatusQueryWrapper);
- if(waitingOrder!= null && waitingOrder.getId()==waitingId && waitingOrder.getNowOrderStatus()==StatusConstant.NOW_ORDER_STATUS_CHARGING){
- logger.info("订单{}已就绪启动充电{}-{}",waitingOrder.getId(),waitingOrder.getPileCode(),waitingOrder.getGunsCode());
- deviceControlerService.startCharge(waitingOrder.getDeviceImei(), waitingOrder.getDeviceImei(), (int) waitingOrder.getGunsCode(),0);
- redisCache.deleteObject(waitingKey);
- return;
- }
- }
- }
- //创建设备端口号
- if (statusServiceOne != null) {
- BeanUtils.copyProperties(statusServiceOne, statusServiceOneTemp);
- } else {
- //禁用的设备不再上线,只看正常设备
- 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());
- statusServiceOne.setOnlineStatus(DeviceOnlineStatus.ONLINE);
- statusServiceOne.setUpdateTime(System.currentTimeMillis());
- statusServiceOne.setPortStatus(portStatus);
- deviceStatusService.saveOrUpdate(statusServiceOne);
- }
- statusServiceOne.setPortStatus(portStatus);
- statusServiceOne.setGunStatus(gunsStatus);
- statusServiceOne.setInsertGunStatus(insertGunStatus);
- statusServiceOne.setOnlineStatus(DeviceOnlineStatus.ONLINE);
- statusServiceOne.setUpdateTime(System.currentTimeMillis());
- deviceStatusService.updateById(statusServiceOne);
- logger.info("{}设备状态持久化>>>" + statusServiceOne.toString(), imei);
- redisCache.setCacheMapValue(port == 1 ? RedisConstant.ONLINE_DEVICE_ONE : RedisConstant.ONLINE_DEVICE_TWO, statusServiceOne.getPileCode(), statusServiceOne);
- //为啥要过期20分
- redisCache.expire(port == 1 ? RedisConstant.ONLINE_DEVICE_ONE : RedisConstant.ONLINE_DEVICE_TWO, 60 * 1001 * 20, TimeUnit.MILLISECONDS);
- DeviceConnectionMsg deviceConnectionMsg = socketHandle.getDeviceConnection(statusServiceOne.getPileCode());
- if (deviceConnectionMsg == null || deviceConnectionMsg.getLoginStatus() != Constant.DEVICE_LOGIN_STATUS) {
- logger.info("设备{}未登录成功不上报", statusServiceOne.getDeviceImei());
- return;
- }
- 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 || one.getNowOrderStatus() != StatusConstant.NOW_ORDER_STATUS_CHARGING) {
- logger.info("没有订单上报空闲{}", imei);
- realTimeStatusPushFrame.deviceStatusPush(deviceConnectionMsg, FrameDataSplicing.transactionNum(null, 0), statusServiceOne.getPileCode(), (byte) port, gunsStatus, insertGunStatus, 0, 0, zero, zero, 0);
- return;
- }
- //充电中
- if (portStatus == PortStatusConstant.CHARGING) {
- byte[] transactionNum = one.getTransOrder();
- if (one.getChargingInitStatus() == StatusConstant.CHARGING_INIT_STATUS_NO) {
- logger.info("{}变位为充电中且当前订单还没首次上报过初始状态:" + DataConversion.bytesToHexString(transactionNum), imei);
- realTimeStatusPushFrame.deviceStatusPush(deviceConnectionMsg, transactionNum, statusServiceOneTemp.getPileCode(), (byte) port, gunsStatus, insertGunStatus, 0, 0, zero, zero, 0);
- //这里上报开始充电初始化状态并记录已经上报首次状态
- one.setChargingInitStatus(StatusConstant.CHARGING_INIT_STATUS_OK);
- orderStatusService.updateById(one);
- }
- return;
- }
- //充电结束
- if (portStatus == PortStatusConstant.CHARGING_END) {
- //7状态小于30秒内且订单原因不是远程停充
- if (one.getNowOrderStatus() == StatusConstant.NOW_ORDER_STATUS_CHARGING) {
- if ((System.currentTimeMillis() - one.getCreateTime()) < 60 * 1000 && one.getReasonStopCharging() != TransConstant.APP_REMOTE_STOP) {
- logger.info("下订单60秒内{}不处理7状态", one.getPileCode());
- return;
- }
- //充电已完成
- //发送结束充电命令 顺利的话113会收到 状态还是7
- logger.info("下订单60秒后{}仍然处于7状态发送止充电指令", one.getPileCode());
- //标记订单为已停充 标记为未上送
- one.setNowOrderStatus(StatusConstant.NOW_ORDER_STATUS_CHARGING_ENDING);
- one.setEndTime(System.currentTimeMillis());
- one.setReasonStopCharging(TransConstant.SOC_FULL_OF_STOP);
- orderStatusService.updateById(one);
- RpcResult rpcResult = deviceControlerService.stopCharge(imei, imei, port);
- return;
- }
- return;
- }
- //先拔 再插
- //订单还在充电中 但是枪不在充电中状态 就结束订单
- // 但是拔了再插 会短暂的从1 变成5 所以在判断空闲的时候 要加上订单60秒的变位限制 6如果有订单60秒后才关闭
- if (one.getNowOrderStatus() == StatusConstant.NOW_ORDER_STATUS_CHARGING) {
- if ((System.currentTimeMillis() - one.getCreateTime()) < 60 * 1000 && one.getReasonStopCharging() != TransConstant.APP_REMOTE_STOP) {
- logger.info("下订单60秒内{}不处理空闲这个状态", one.getPileCode());
- return;
- }
- logger.info("{}枪非充电中状态,结束订单状态 等待任务重试上报订单", one.getPileCode());
- one.setNowOrderStatus(StatusConstant.NOW_ORDER_STATUS_CHARGING_ENDING);
- one.setEndTime(System.currentTimeMillis());
- one.setReasonStopCharging(TransConstant.OTHER_STOP);
- orderStatusService.updateById(one);
- }
- logger.info("上传空闲状态{}",imei);
- realTimeStatusPushFrame.deviceStatusPush(deviceConnectionMsg, FrameDataSplicing.transactionNum(null, 0), statusServiceOne.getPileCode(), (byte) port, gunsStatus, insertGunStatus, 0, 0, zero, zero, 0);
- }
- }
|