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

import com.bsth.data.BasicData;
import com.bsth.data.LineConfigData;
import com.bsth.data.gpsdata.GpsEntity;
import com.bsth.data.gpsdata.GpsRealData;
import com.bsth.data.gpsdata.status_manager.GpsStatusManager;
import com.bsth.data.msg_queue.DirectivePushQueue;
import com.bsth.data.schedule.DayOfSchedule;
import com.bsth.entity.Line;
import com.bsth.entity.directive.D80;
import com.bsth.entity.directive.DC0_A4;
import com.bsth.entity.realcontrol.D80ReplyTemp;
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.directive.DirectiveService;
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.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;

    //private static ArrayListMultimap<String, D80> d80MultiMap;

    private static ConcurrentHashMap<Integer, D80> d80Maps;

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

    static {
        //d80MultiMap = ArrayListMultimap.create();
        d80Maps = new ConcurrentHashMap<>();
    }

    public void report(D80 d80) {
        if (d80 == null)
            return;
        try {
            //入库
            d80Repository.save(d80);
            //入缓存
            d80Maps.put(d80.getId(), d80);
            //d80MultiMap.put(d80.getData().getLineId().toString(), 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:
                    ScheduleRealInfo outSch = dayOfSchedule.searchNearByBcType(nbbm, "out");
                    //如果有对应出场班次
                    if (outSch != null) {
                        //没有计划里程的出场班次,出场既是首发站,发送下一班次的调度指令
                        if (outSch.getJhlc() == null)
                            outSch = dayOfSchedule.next(outSch);

                        //下发调度指令
                        String deviceId = d80.getDeviceId();
                        DirectivePushQueue.put6002(outSch, dayOfSchedule.doneSum(nbbm), "请出@系统");

                        //下发线路切换指令
                        DirectivePushQueue.put64(outSch.getClZbh(), outSch.getXlBm(), "请出@系统");

                        try {
                            GpsEntity gps = gpsRealData.get(deviceId);
                            if(gps != null && !gps.isService()){
                                //切换到营运状态
                                gpsStatusManager.changeServiceState(nbbm, outSch.getXlDir() ,0, "请出@系统");
                            }
                        }catch (Exception e){
                            logger.error("请出切换营运状态异常", e);
                        }
                    }
                    break;
            }

            //推送到页面
            sendUtils.send80ToPage(d80);

            //反射搜索用 瞬时字段
            d80.setLineId(d80.getData().getLineId());
            d80.setNbbm(d80.getData().getNbbm());
            d80.setRequestCode(d80.getData().getRequestCode());
        } catch (Exception e) {
            logger.error("", 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) {
        String nbbm = BasicData.deviceId2NbbmMap.get(d80.getDeviceId());
        Short reqCode = d80.getData().getRequestCode();
        //默认短语回复
        //defaultReply(nbbm, reqCode, d80.getConfirmRs() == 0?true:false);

        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);
    }

    public void defaultReply(String nbbm, short requestCode, boolean agree) {
        Line line = BasicData.nbbm2LineMap.get(nbbm);
        String lineCode = null;

        if (line != null)
            lineCode = line.getLineCode();
        else {
            try {
                lineCode = gpsRealData.get(BasicData.deviceId2NbbmMap.inverse().get(nbbm)).getLineId().toString();
            } catch (Exception e) {
                logger.error("", e);
            }
        }

        if (null == lineCode)
            return;

        LineConfig conf = lineConfigData.get(lineCode);
        D80ReplyTemp temp = conf.findByCode(requestCode);

        if (null == temp)
            return;

        String text;
        if (agree)
            text = temp.getAgreeText();
        else
            text = temp.getRejectText();

        directiveService.send60Phrase(nbbm, text, "系统");
    }

    /**
     * @Title: resumeOperation
     * @Description: TODO(恢复营运)
     */
    public void resumeOperation(D80 d80) {

    }

    /**
     * @Title: applyTiaodang
     * @Description: TODO(申请调档)
     */
    public void applyTiaodang(D80 d80) {

    }

    /**
     * @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 String coordHtmlStr(GpsEntity gps) {

        return "<span class=\"nt-coord\" data-lon=\"" + gps.getLon() + "\" data-lat=\"" + gps.getLat() + "\"></span>";
    }*/

    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());
        }
        logger.info("清除 80数据 after: " + d80Maps.size());
    }

    public Collection<? extends D80> findByCar(String nbbm) {
        List<D80> rs = new ArrayList<>();
        String deviceId = BasicData.deviceId2NbbmMap.inverse().get(nbbm);
        if (null == deviceId)
            return rs;

        Collection<D80> all = findAll();
        for (D80 d80 : all) {
            if (d80.getDeviceId().equals(deviceId))
                rs.add(d80);
        }
        return rs;
    }
}