DirectiveBuffer.java 6.3 KB
package com.bsth.vehicle.directive.buffer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bsth.entity.realcontrol.ScheduleRealInfo;
import com.bsth.service.realcontrol.buffer.ScheduleBuffer;
import com.bsth.vehicle.common.CommonMapped;
import com.bsth.vehicle.directive.entity.Directive60;
import com.bsth.vehicle.directive.entity.DirectiveReply;
import com.bsth.vehicle.directive.entity.Directive80;
import com.bsth.vehicle.directive.entity.DirectiveC0;
import com.bsth.vehicle.directive.entity.DirectiveC0.DirectiveC0Data;
import com.bsth.vehicle.directive.entity.LineChange;
import com.bsth.vehicle.directive.repository.Directive60Repository;
import com.bsth.vehicle.directive.repository.Directive80Repository;
import com.bsth.vehicle.directive.repository.LineChangeRepository;
import com.bsth.vehicle.directive.service.DirectiveService;
import com.bsth.vehicle.directive.util.HttpUtils;
import com.bsth.websocket.handler.RealControlSocketHandler;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

/**
 * 
 * @ClassName: DirectiveBuffer 
 * @Description: TODO(调度指令缓存) 
 * @author PanZhao
 * @date 2016年6月7日 下午3:24:19 
 *
 */
@Component
public class DirectiveBuffer {
	
	Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	Directive80Repository d80Repository;
	
	@Autowired
	LineChangeRepository lineChangeRepository;
	
	@Autowired
	DirectiveService directiveService;
	
	
	/**
	 * 等待入库的调度指令
	 */
	public static LinkedList<Directive60> transientList;
	
	/**
	 * 等待确认的线路切换指令
	 */
	public static Map<String, LineChange> changeMap;
	
	/**
	 * 当日调度指令缓存
	 */
	private static Map<Integer, Directive60> directiveMap;
	
	@Autowired
	Directive60Repository d60Repository;
	
	/**
	 * 驾驶员上报数据
	 * {K: 线路编码}
	 */
	private static Multimap<Integer, Directive80> reportMultiMap;
	
	@Autowired
	RealControlSocketHandler socketHandler;
	
	static{
		clear();
	}
	
	public static void put(Directive60 directive){
		directiveMap.put(directive.getMsgId(), directive);
	}
	
	/**
	 * 
	 * @Title: reply 
	 * @Description: TODO(指令 46,47 响应) 
	 * @throws
	 */
	public void reply(DirectiveReply reply){
		Integer msgId = reply.getMsgId();
		if(msgId == null){
			logger.error("reply error , msgId is null.");
			return;
		}
		
		Directive60 directive = directiveMap.get(msgId);
		
		if(null == directive){
			//无效的响应
			return;
		}
		
		switch (reply.getStatus()) {
		case 0:
			//失败
			directive.setReply46((short)-1);
			break;

		case 1:
			//发送成功
			directive.setReply46((short)0);
			break;
		case 2:
			//驾驶员阅读
			directive.setReply47((short)0);
			break;
		}
		
		if(directive.isDispatch()){
			//更新班次状态
			ScheduleRealInfo sch = directive.getSch();
			sch.setDirectiveState(reply.getStatus() * 100);
			ScheduleBuffer.persistentList.add(sch);
			//通知页面
			directiveService.sendDirectiveToPage(sch);
		}
		transientList.add(directive);
	}
	
	/**
	 * 
	 * @Title: reply64 
	 * @Description: TODO(64 协议响应) 
	 * @throws
	 */
	public void reply64(JSONObject json){
		String key = json.getString("deviceId") + "_" + json.getString("timestamp");
		
		LineChange change = changeMap.get(key);
		
		if(null == change)
			logger.warn("64响应 -找不到请求源,json: " + json);
		else{
			JSONObject data = json.getJSONObject("data");
			
			changeMap.remove(key);
			
			if(null == data)
				logger.warn("64响应 data is null ,json: " + json);
			else{
				change.setRespAck(data.getShort("requestAck"));
				//响应入库
				lineChangeRepository.save(change);
			}
		}
	}
	
	/**
	 * 
	 * @Title: jsyReport 
	 * @Description: TODO(80 驾驶员上报) 
	 * @throws
	 */
	public void jsyReport(Directive80 report){
		//将托管的线路自动处理掉
		Integer lineCode = report.getData().getLineId();
		Integer status = ScheduleBuffer.trustMap.get(lineCode);
		//请求代码
		Short requestCode = report.getData().getRequestCode();
		//托管
		if(null == status || status == 0){
			//自动处理出场请求
			if(requestCode == 0xA3){
				DirectiveC0 c0 = createC0(report, (short)0x06);
				HttpUtils.postJson(JSON.toJSONString(c0));
				report.setC0(c0);
				d80Repository.save(report);
			}
		}
		
		//实时入库
		d80Repository.save(report);
		reportMultiMap.put(lineCode, report);
		//推送到页面
		report.getData().setNbbm(CommonMapped.vehicDeviceBiMap.get(report.getDeviceId()));
		JSONObject json = JSONObject.parseObject(JSONObject.toJSONString(report));
		json.put("fn", "report80");
 		socketHandler.sendMessageToLine(lineCode, json.toJSONString());
	}
	
	/**
	 * 
	 * @Title: createC0 
	 * @Description: TODO(生成C0数据) 
	 * @param @param ack
	 * @throws
	 */
	public DirectiveC0 createC0(Directive80 report, short ack){
		DirectiveC0 c0 = new DirectiveC0();
		c0.setDeviceId(report.getDeviceId());
		c0.setTimestamp(report.getTimestamp());
		c0.setOperCode((short)0xC0);
		
		DirectiveC0Data data = new DirectiveC0Data();
		data.setOperCode2((short)0x86);
		data.setRequestAck(ack);
		
		c0.setData(data);
		return c0;
	}
	
	/**
	 * 
	 * @Title: saveAll 
	 * @Description: TODO(所有缓存里的指令全部入库) 
	 */
	public void saveAll(){
		Iterator<Directive60> iterator = directiveMap.values().iterator();
		List<Directive60> pList = new ArrayList<>();
		Directive60 d60;
		while(iterator.hasNext()){
			d60 = iterator.next();
			if(!d60.isPersistent())
				pList.add(d60);
		}
		d60Repository.save(pList);
	}
	
	/**
	 * 
	 * @Title: clear 
	 * @Description: TODO(清理缓存) 
	 * @throws
	 */
	public static void clear(){
		transientList = new LinkedList<>();
		directiveMap = new HashMap<>();
		reportMultiMap = ArrayListMultimap.create();
		changeMap = new HashMap<>();
	}
}