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

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

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
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.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.Directive;
import com.bsth.vehicle.directive.entity.Directive.DirectiveData;
import com.bsth.vehicle.directive.entity.DispatchInstruct;
import com.bsth.vehicle.directive.entity.LineChange;
import com.bsth.vehicle.directive.entity.LineChange.LineChangeData;
import com.bsth.vehicle.directive.repository.DirectiveRepository;
import com.bsth.vehicle.directive.repository.LineChangeRepository;
import com.bsth.vehicle.gpsdata.buffer.GpsRealDataBuffer;
import com.bsth.vehicle.gpsdata.entity.GpsRealData;

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

	Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	DirectiveRepository directiveRepository;
	
	@Autowired
	GpsRealDataBuffer gpsRealDataBuffer;
	
	@Autowired
	LineChangeRepository lineChangeRepository;
	
	SimpleDateFormat sdfHHmm = new SimpleDateFormat("HH点mm分");
	
	static Long schDiff = 1000 * 60 * 6L;
	
	//城市代码
	static final short cityCode = 22;
	
	@Override
	public int send60Phrase(String nbbm, String text) {
		Directive directive = null;
		try {
			directive = create60Data(nbbm, text, DispatchInstruct.PHRASE);
		} catch (Exception e) {
			logger.error("发送消息短语出现异常", e);
			return -1;
		}
		
		if(null == directive)
			return -1;
		
		//发送指令
		int code = 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) {
		Directive 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, DispatchInstruct.PHRASE);
		} catch (Exception e) {
			logger.error("生成调度指令时出现异常", e);
			return -1;
		}
		
		if(null == directive)
			return -1;
		
		//发送指令
		int code = postJson(JSON.toJSONString(directive));
		
		if(code == 0){
			sch.setDirectiveState(60);
			//添加到缓存,等待入库
			directive.setDispatch(true);
			directive.setSch(sch);
			DirectiveBuffer.put(directive);
		}else{
			logger.error("send60Phrase error, code: " + code);
		}
		return code;
	}

	@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(String.valueOf(lineId));
		
		change.setDeviceId(deviceId);
		change.setOperCode((short) 0X64);
		change.setTimestamp(t);
		change.setData(data);
		
		int code = postJson(JSON.toJSONString(change));
		if(code == 0){
			//入库
			lineChangeRepository.save(change);
			DirectiveBuffer.changeMap.put(deviceId + '_'  + t , change);
			//通知设备刷新线路文件,忽略结果
			postJson(createDeviceRefreshData(deviceId, lineId));
		}else{
			logger.error("send60Phrase error, code: " + code);
		}
		return code;
	}
	
	
	public Directive create60Data(String nbbm, String text, DispatchInstruct dispatchInstruct){
		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;
		}
		GpsRealData gpsData = gpsRealDataBuffer.findOneByDeviceId(deviceId);
		if(null == gpsData){
			logger.error("没有找到gps对照,无法确认营运状态和上下行:" + nbbm);
			return null;
		}
		
		int msgId = MsgIdGenerator.getMsgId();
		
		Directive directive = new Directive();
		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[gpsData.getUpDown()][gpsData.getState()];
		}catch(IndexOutOfBoundsException e){
			//未知营运状态的直接默认为上行非营运
			serviceState = Consts.SERVICE_STATE[0][1];
		}
		data.setServiceState(serviceState);
		data.setTxtContent(text);
		
		return directive;
	}
	
	public int postJson(String jsonStr){
		logger.info("send : " + jsonStr);
		
		CloseableHttpClient httpClient = null;
		int code = -1;
		try{
			httpClient = HttpClients.createDefault();
			
			HttpPost post = new HttpPost(Consts.SEND_DIRECTIVE_URL);
			
			post.setEntity(new StringEntity(jsonStr, "utf-8"));
		
			CloseableHttpResponse response = httpClient.execute(post);
			
			JSONObject json = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
			if(null != json && json.getInteger("errCode") == 0)
				code = 0;
			else
				logger.error("和网关http通讯失败,rs: " + json);
		}catch(Exception e){
			logger.error("", e);
		}finally {
			try {
				if(httpClient != null)
					httpClient.close();
			} catch (IOException e) {
				logger.error("", e);
			}
		}
		return code;
	}

	@Override
	public int upDownChange(String nbbm, Integer upDonw) {
		//构造数据
		String deviceId = CommonMapped.vehicDeviceBiMap.inverse().get(nbbm);
		Short company = Short.parseShort(CommonMapped.vehicCompanyMap.get(nbbm));
		Long timestamp = System.currentTimeMillis();
		int msgId = MsgIdGenerator.getMsgId();
		Directive directive = new Directive();
		DirectiveData data = new DirectiveData();
		//一级协议
		directive.setOperCode((short) 0x60);
		//设备号
		directive.setDeviceId(deviceId);
		//时间戳
		directive.setTimestamp(timestamp);
		directive.setMsgId(msgId);
		//构造数据
		data.setDeviceId(deviceId);
		data.setDispatchInstruct(DispatchInstruct.OPERATE_CLOCK_OFF);
		data.setTimestamp(timestamp);
		data.setCompanyCode(company);
		data.setMsgId(msgId);
		directive.setData(data);
		
		long serviceState;
		try{
			serviceState = Consts.SERVICE_STATE[upDonw][0];
		}catch(IndexOutOfBoundsException e){
			logger.error("upDonw: " + upDonw, e);
			return -1;
		}
		data.setServiceState(serviceState);
		
		int code = postJson(JSON.toJSONString(directive));
		if(code == 0){
			//添加到缓存,等待入库
			DirectiveBuffer.put(directive);
		}else{
			logger.error("send60 upDownChange error, code: " + code);
		}
		return 0;
	}
	
	/**
	 * 
	 * @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);
	}
}