PilotReport.java 10.7 KB
package com.bsth.data.pilot80;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bsth.data.BasicData;
import com.bsth.data.LineConfigData;
import com.bsth.data.gpsdata_v2.GpsRealData;
import com.bsth.data.gpsdata_v2.status_manager.GpsStatusManager;
import com.bsth.data.msg_queue.DirectivePushQueue;
import com.bsth.data.schedule.DayOfSchedule;
import com.bsth.entity.directive.D80;
import com.bsth.entity.directive.DC0_A4;
import com.bsth.entity.realcontrol.LineConfig;
import com.bsth.entity.realcontrol.ScheduleRealInfo;
import com.bsth.repository.directive.D80Repository;
import com.bsth.repository.directive.DC0A4Repository;
import com.bsth.service.SystemParamService;
import com.bsth.service.directive.DirectiveService;
import com.bsth.util.HttpClientUtils;
import com.bsth.websocket.handler.SendUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author PanZhao
 * @ClassName: PilotReport
 * @Description: TODO(设备80协议上报处理)
 * @date 2016年8月14日 下午11:37:51
 */
@Component
public class PilotReport {

    @Autowired
    D80Repository d80Repository;
    @Autowired
    DayOfSchedule dayOfSchedule;
    @Autowired
    LineConfigData lineConfigData;
    @Autowired
    DirectiveService directiveService;
    @Autowired
    GpsRealData gpsRealData;
    @Autowired
    SendUtils sendUtils;

    @Autowired
    DC0A4Repository dc0A4Repository;

    @Autowired
    GpsStatusManager gpsStatusManager;

    @Autowired
    private SystemParamService systemParamService;
    private static ConcurrentHashMap<Integer, D80> d80Maps;

    /**
     * 设备 ——> 最后一条请求出场记录
     */
    public static ConcurrentHashMap<String, D80> qqccMap;

    Logger logger = LoggerFactory.getLogger(PilotReport.class);

    static {
        d80Maps = new ConcurrentHashMap<>();
        qqccMap = new ConcurrentHashMap<>();
    }

    public void report(D80 d80) {
        if (d80 == null)
            return;
        try {
            //入库
            d80Repository.save(d80);
            //入缓存
            d80Maps.put(d80.getId(), d80);

            String nbbm = BasicData.deviceId2NbbmMap.get(d80.getDeviceId());
            //上报时,在执行的班次
            if(StringUtils.isNotEmpty(nbbm)){
                ScheduleRealInfo sch = dayOfSchedule.executeCurr(nbbm);
                if(null != sch)
                    d80.setSchId(sch.getId());
            }
            //处理
            switch (d80.getData().getRequestCode()) {
                //出场请求
                case 0xA3:
                    qqccMap.put(d80.getDeviceId(), d80);
                    ScheduleRealInfo outSch = dayOfSchedule.searchNearByBcType(nbbm, "out");
                    //如果有对应出场班次
                    if (outSch != null && StringUtils.isEmpty(outSch.getFcsjActual())) {
                        //没有计划里程的出场班次,出场既是首发站,发送下一班次的调度指令
                        if (outSch.getJhlc() == null)
                            outSch = dayOfSchedule.next(outSch);
                        //下发调度指令
                        DirectivePushQueue.put60_002(outSch, dayOfSchedule.doneSum(nbbm), "请出@系统", "同意出场;");
                    }
                    break;
                //报警请求
                case 0x21:
                case 0x22:
                case 0x23:
                case 0x24:
                    yjbj(nbbm,d80);
                    break;
            }

            //反射搜索用 瞬时字段
            d80.setLineId(d80.getData().getLineId());
            d80.setNbbm(d80.getData().getNbbm());
            d80.setRequestCode(d80.getData().getRequestCode());

            //推送到页面
            sendUtils.send80ToPage(d80);
        } catch (Exception e) {
            logger.error("", e);
        }
    }

    public void yjbj(String nbbm,D80 d80){
        try {
            ScheduleRealInfo sch = null;

            if (d80.getData().getStopNo() != null && !d80.getData().getStopNo().equals("")){
                d80.setStationName(BasicData.stationCode2NameMap.get(d80.getData().getStopNo()));
            }
            if (d80.getSchId() != null){
                sch = dayOfSchedule.get(d80.getSchId());
            }
            if (sch == null){
                // 查找离发车时间最近的班次
                long currentTime = new Date().getTime();
                long minTimeDiff = Long.MAX_VALUE;
                List<ScheduleRealInfo> schlist =  dayOfSchedule.findByNbbm(nbbm);
                for (ScheduleRealInfo schedule : schlist) {
                    // 检查计划发车时间
                    if (schedule.getDfsjT() != null) {
                        long timeDiff = Math.abs(currentTime - schedule.getDfsjT());
                        if (timeDiff < minTimeDiff) {
                            minTimeDiff = timeDiff;
                            sch = schedule;
                        }
                    }
                }

            }

            String url = systemParamService.getValue("url.yjbj")+"dataDockingApi/accident/saveAccident?";
            url = url + "accidentTime=" + new Date().getTime() + "&nbbm=" + nbbm +"&requestCode=" +d80.getData().getRequestCode()
                    +"&lon=" +d80.getData().getLon()+"&lat="+d80.getData().getLat();
            if (sch != null){
                url = url + "&lineName=" +sch.getXlName()+"&jsy=" +sch.getjGh()+"&jsName=" +sch.getjName()+"&fgs="+sch.getFgsBm();
            }
            logger.info("url===="+url);
            StringBuilder sb = HttpClientUtils.get(url);


            JSONObject jsonObject = JSON.parseObject(sb.toString());
            if ((int) jsonObject.get("code") == 200) {
                logger.info("报警请求成功=" + jsonObject.get("msg"));
            }else {
                logger.info("报警请求失败="+ jsonObject.get("msg"));
            }
            if (d80.getSchId() != null && dayOfSchedule.nextByLp(sch) != null){
                Long nextschid = dayOfSchedule.nextByLp(sch).getId();
                d80.setNextschId(nextschid);
            }
        }catch (Exception e){
            logger.info("报警请求异常",e);
        }
    }

    public void report(DC0_A4 c0a4) {
        String deviceId = c0a4.getData().getDeviceId();
        if (StringUtils.isNotEmpty(deviceId))
            c0a4.setId(deviceId);

        //入库
        dc0A4Repository.save(c0a4);
    }

    /**
     * @Title: reply
     * @Description: TODO(调度员回复)
     */
    public void reply(D80 d80) {
        Short reqCode = d80.getData().getRequestCode();

        switch (reqCode) {
            case 0xA3:
                //出场请求回复
                applyOutReply(d80);
                break;
            case 0xA5:
                //进场请求回复
                applyInReply(d80);
                break;
        }
    }

    /**
     * @Title: applyOutReply
     * @Description: TODO(出场请求回复)
     */
    public void applyOutReply(D80 d80) {
        //同意
        if (d80.getConfirmRs() == 0) {
            String nbbm = BasicData.deviceId2NbbmMap.get(d80.getDeviceId());

            ScheduleRealInfo sch = dayOfSchedule.searchNearByBcType(nbbm, "out");
            if (null == sch)
                return;

            LineConfig conf = lineConfigData.get(sch.getXlBm());
            if (conf.getOutConfig() == 1) {

                try{
                    //最大允许时间阈值 2 小时
                    if(Math.abs(d80.getTimestamp() - sch.getDfsjT()) > 1000 * 60 * 60 * 2)
                        return;
                }catch (Exception e){
                    logger.error("", e);
                }

                //为相关班次写入请求出场时间
                sch.setFcsjActualAll(d80.getTimestamp());

                dayOfSchedule.save(sch);
                //通知页面
                sendUtils.refreshSch(sch);
            }
        }
    }

    /**
     * @Title: applyInReply
     * @Description: TODO(进场请求回复)
     */
    public void applyInReply(D80 d80) {
        //同意
        if (d80.getConfirmRs() == 0) {
            String nbbm = BasicData.deviceId2NbbmMap.get(d80.getDeviceId());

            ScheduleRealInfo sch = dayOfSchedule.nextByBcType(nbbm, "in");
            if (null == sch)
                return;

            LineConfig conf = lineConfigData.get(sch.getXlBm());
            if (conf.getOutConfig() == 1) {
                //为相关班次写入进场时间
                sch.setZdsjActualAll(d80.getTimestamp());

                //没有里程的进场班次
                if (isEmpty(sch.getBcsj()) && isEmpty(sch.getJhlc()))
                    sch.setFcsjActualAll(d80.getTimestamp());

                dayOfSchedule.save(sch);
                //通知页面
                sendUtils.refreshSch(sch);
            }
        }
    }

    public boolean isEmpty(Integer v) {
        return v == null || v.equals(0);
    }

    public boolean isEmpty(Double v) {
        return v == null || v.equals(0.0);
    }

    /**
     * @Title: unconfirmed80
     * @Description: TODO(根据lineCode 获取未处理的80数据)
     */
    public List<D80> unconfirmed80(String lineCode) {
        List<D80> lineAll = findByLine(lineCode), rs = new ArrayList<>();

        for (D80 d80 : lineAll)
            if (!d80.isConfirm())
                rs.add(d80);

        return rs;
    }

    public List<D80> findByLine(String lineCode) {
        List<D80> rs = new ArrayList<>();
        for (D80 d80 : d80Maps.values()) {
            if (d80 != null && d80.getData().getLineId().equals(lineCode))
                rs.add(d80);
        }
        return rs;
    }

    public D80 findById(int id) {
        return d80Maps.get(id);
    }


    public Collection<D80> findAll() {
        return d80Maps.values();
    }

    public void clear(String lineCode) {
        logger.info("清除 80数据 before: " + d80Maps.size());
        List<D80> rems = findByLine(lineCode);
        for (D80 d80 : rems) {
            d80Maps.remove(d80.getId());
            qqccMap.remove(d80.getDeviceId());
        }

        rems.clear();
        logger.info("清除 80数据 after: " + d80Maps.size());
    }
}