DirectiveServiceImpl.java 9.24 KB
package com.bsth.vehicle.directive.service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bsth.entity.realcontrol.ScheduleRealInfo;
import com.bsth.service.impl.BaseServiceImpl;
import com.bsth.service.realcontrol.buffer.ScheduleBuffer;
import com.bsth.vehicle.common.CommonMapped;
import com.bsth.vehicle.directive.Consts;
import com.bsth.vehicle.directive.MsgIdGenerator;
import com.bsth.vehicle.directive.buffer.DirectiveBuffer;
import com.bsth.vehicle.directive.entity.Directive60;
import com.bsth.vehicle.directive.entity.Directive60.DirectiveData;
import com.bsth.vehicle.directive.entity.LineChange;
import com.bsth.vehicle.directive.entity.LineChange.LineChangeData;
import com.bsth.vehicle.directive.repository.Directive60Repository;
import com.bsth.vehicle.directive.repository.LineChangeRepository;
import com.bsth.vehicle.directive.util.HttpUtils;
import com.bsth.vehicle.gpsdata.buffer.GpsRealDataBuffer;
import com.bsth.vehicle.gpsdata.entity.GpsRealData;
import com.bsth.websocket.handler.RealControlSocketHandler;

@Service
public class DirectiveServiceImpl extends BaseServiceImpl<Directive60, Integer> implements DirectiveService{

	Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	Directive60Repository directiveRepository;
	
	@Autowired
	GpsRealDataBuffer gpsRealDataBuffer;
	
	@Autowired
	LineChangeRepository lineChangeRepository;
	
	@Autowired
	RealControlSocketHandler socketHandler;
	
	SimpleDateFormat sdfHHmm = new SimpleDateFormat("HH点mm分");
	
	static Long schDiff = 1000 * 60 * 60L;
	
	//城市代码
	static final short cityCode = 22;
	
	@Override
	public int send60Phrase(String nbbm, String text) {
		Directive60 directive = null;
		try {
			directive = create60Data(nbbm, text, (short)0x00, null);
		} catch (Exception e) {
			logger.error("发送消息短语出现异常", e);
			return -1;
		}
		
		if(null == directive)
			return -1;
		
		//发送指令
		int code = HttpUtils.postJson(JSON.toJSONString(directive));
		
		if(code == 0){
			//添加到缓存,等待入库
			DirectiveBuffer.put(directive);
		}else{
			logger.error("send60Phrase error, code: " + code);
		}
		return code;
	}
	
	@Override
	public int send60Dispatch(ScheduleRealInfo sch,  int finish) {
		Directive60 directive = null;
		try {
			//如果发车时间距当前时间较远,则不发送
			if(Math.abs(sch.getFcsjT() - System.currentTimeMillis()) > schDiff){
				return 0;
			}
			
			String text = "已完成" + finish + "个班次,下一发车时间" + sdfHHmm.format(new Date(sch.getFcsjT()))
					+ ",由" + sch.getQdzName() + "发往" + sch.getZdzName();
			
			//目前使用短语协议下发调度指令
			directive = create60Data(sch.getClZbh(), text, (short)0x00, sch);
		} catch (Exception e) {
			logger.error("生成调度指令时出现异常", e);
			return -1;
		}
		
		if(null == directive)
			return -1;
		
		//发送指令
		int code = HttpUtils.postJson(JSON.toJSONString(directive));
		
		if(code == 0){
			sch.setDirectiveState(60);
			//添加到缓存,等待入库
			directive.setDispatch(true);
			directive.setSch(sch);
			DirectiveBuffer.put(directive);
			//通知页面,消息已发出
			sendDirectiveState(sch);
		}else{
			logger.error("send60Phrase error, code: " + code);
		}
		return code;
	}
	
	/**
	 * 
	 * @Title: sendDirectiveState 
	 * @Description: TODO(向页面推送班次指令状态) 
	 * @throws
	 */
	public void sendDirectiveState(ScheduleRealInfo sch){
		JSONObject json = new JSONObject();
		json.put("fn", "directive");
		json.put("t", sch);
		socketHandler.sendMessageToLine(Integer.parseInt(sch.getXlBm()), json.toJSONString());
	}

	
	@Override
	public int send60Dispatch(Long id) {
		ScheduleRealInfo sch = ScheduleBuffer.findOne(id);
		//车辆已完成班次
		int finish = ScheduleBuffer.getFinishSchNo(sch.getClZbh());
		return send60Dispatch(sch, finish);
	}
	
	@Override
	public int send60Operation(String nbbm, int state, int upDown) {
		return 0;
	}

	/**
	 * 线路切换
	 */
	@Override
	public int lineChange(String nbbm, Integer lineId) {
		Long t = System.currentTimeMillis();
		String deviceId = CommonMapped.vehicDeviceBiMap.inverse().get(nbbm);
		
		LineChange change = new LineChange();
		LineChangeData data = new LineChangeData();
		data.setCityCode(cityCode);
		data.setDeviceId(deviceId);
		data.setLineId("00" + String.valueOf(lineId));
		
		change.setDeviceId(deviceId);
		change.setOperCode((short) 0X64);
		change.setTimestamp(t);
		change.setData(data);
		
		int code = HttpUtils.postJson(JSON.toJSONString(change));
		if(code == 0){
			//入库
			lineChangeRepository.save(change);
			DirectiveBuffer.changeMap.put(deviceId + '_'  + t , change);
			//通知设备刷新线路文件,忽略结果
			HttpUtils.postJson(createDeviceRefreshData(deviceId, lineId));
		}else{
			logger.error("send60Phrase error, code: " + code);
		}
		return code;
	}
	
	
	public Directive60 create60Data(String nbbm, String text, Short dispatchInstruct, ScheduleRealInfo sch){
		Long timestamp = System.currentTimeMillis();
		
		/*//向测试设备发送
		String deviceId = "ABCDFEGH";
		Short company = 5;*/
		
		String deviceId = CommonMapped.vehicDeviceBiMap.inverse().get(nbbm);
		Short company = Short.parseShort(CommonMapped.vehicCompanyMap.get(nbbm));
		if(null == deviceId){
			logger.error("没有设备号对照的车辆:" + nbbm);
			return null;
		}
		//上下行和营运状态
		Integer upDown = null, state = null;
		if(null == sch){
			GpsRealData gpsData = gpsRealDataBuffer.findOneByDeviceId(deviceId);
			if(null == gpsData){
				logger.error("没有找到gps对照,无法确认营运状态和上下行:" + nbbm);
				return null;
			}
			upDown = gpsData.getUpDown();
			state = gpsData.getState();
		}
		else{
			upDown = Integer.parseInt(sch.getXlDir());
			state = 0;
		}
		
		
		int msgId = MsgIdGenerator.getMsgId();
		
		Directive60 directive = new Directive60();
		DirectiveData data = new DirectiveData();
		//一级协议
		directive.setOperCode((short) 0x60);
		//设备号
		directive.setDeviceId(deviceId);
		//时间戳
		directive.setTimestamp(timestamp);
		directive.setMsgId(msgId);
		//构造数据
		data.setDeviceId(deviceId);
		data.setDispatchInstruct(dispatchInstruct);
		data.setTimestamp(timestamp);
		data.setCompanyCode(company);
		data.setMsgId(msgId);
		directive.setData(data);
		long serviceState;
		try{
			serviceState = Consts.SERVICE_STATE[upDown][state];
		}catch(IndexOutOfBoundsException e){
			//未知营运状态的直接默认为上行非营运
			serviceState = Consts.SERVICE_STATE[0][1];
		}
		data.setServiceState(serviceState);
		data.setTxtContent(text);
		
		return directive;
	}
	
	@Override
	public int upDownChange(String nbbm, Integer upDown) {
		//构造数据
		String deviceId = CommonMapped.vehicDeviceBiMap.inverse().get(nbbm);
		Short company = Short.parseShort(CommonMapped.vehicCompanyMap.get(nbbm));
		Long timestamp = System.currentTimeMillis();
		int msgId = MsgIdGenerator.getMsgId();
		Directive60 directive = new Directive60();
		DirectiveData data = new DirectiveData();
		//一级协议
		directive.setOperCode((short) 0x60);
		//设备号
		directive.setDeviceId(deviceId);
		//时间戳
		directive.setTimestamp(timestamp);
		directive.setMsgId(msgId);
		//构造数据
		data.setDeviceId(deviceId);
		data.setDispatchInstruct((short)0x03);
		data.setTimestamp(timestamp);
		data.setCompanyCode(company);
		data.setMsgId(msgId);
		data.setTxtContent(nbbm + "_" + upDown);
		directive.setData(data);
		
		long serviceState;
		try{
			serviceState = Consts.SERVICE_STATE[upDown][0];
		}catch(IndexOutOfBoundsException e){
			logger.error("upDonw: " + upDown, e);
			return -1;
		}
		data.setServiceState(serviceState);
		
		int code = HttpUtils.postJson(JSON.toJSONString(directive));
		if(code == 0){
			//添加到缓存,等待入库
			DirectiveBuffer.put(directive);
		}else{
			logger.error("send60 upDownChange error, code: " + code);
		}
		return code;
	}
	
	/**
	 * 
	 * @Title: createDeviceRefreshData 
	 * @Description: TODO(生成设备线路刷新数据包) 
	 * @param @return    设定文件 
	 * @return String    返回类型 
	 * @throws
	 */
	public String createDeviceRefreshData(String deviceId, Integer lineId){
		Long t =  System.currentTimeMillis();
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("deviceId", deviceId);
		param.put("timestamp", t);
		param.put("operCode", 0Xc0);
		
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("operCode", 0xa1);
		data.put("cityCode", cityCode);
		data.put("deviceId", deviceId);
		data.put("timestamp", t);
		data.put("centerId", 1);
		data.put("lineId", lineId);
		data.put("lineVersion", 0);
		data.put("carparkDataVersion", 0);
		param.put("data", data);
		
		return JSON.toJSONString(param);
	}
}