CamelDataUtil.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. package org.dromara.util;
  2. import cn.hutool.core.date.DateUtil;
  3. import cn.hutool.core.util.CharsetUtil;
  4. import cn.hutool.core.util.StrUtil;
  5. import cn.hutool.json.JSON;
  6. import cn.hutool.json.JSONArray;
  7. import cn.hutool.json.JSONUtil;
  8. import io.netty.buffer.ByteBuf;
  9. import io.netty.buffer.Unpooled;
  10. import io.netty.channel.ChannelHandlerContext;
  11. import lombok.extern.slf4j.Slf4j;
  12. import org.apache.camel.CamelContext;
  13. import org.apache.camel.Exchange;
  14. import org.apache.camel.ProducerTemplate;
  15. import org.apache.commons.lang3.time.DateFormatUtils;
  16. import org.dromara.common.core.constant.Constants;
  17. import org.dromara.common.core.utils.DateUtils;
  18. import org.dromara.common.core.utils.SpringUtils;
  19. import org.dromara.common.core.utils.StringUtils;
  20. import org.dromara.common.json.utils.JsonUtils;
  21. import org.dromara.common.redis.utils.RedisUtils;
  22. import org.dromara.netty.pojo.NettyChannelHandlerContext;
  23. import org.dromara.sms4j.api.universal.RedisUtil;
  24. import org.dromara.system.domain.CountData;
  25. import org.dromara.system.domain.GpsData;
  26. import org.dromara.system.domain.SysDictData;
  27. import org.dromara.system.domain.TblCarInfo;
  28. import org.dromara.system.domain.bo.CountDataBo;
  29. import org.dromara.system.domain.bo.SysDictDataBo;
  30. import org.dromara.system.domain.bo.TblCarInfoBo;
  31. import org.dromara.system.domain.bo.TblCarScheduleBo;
  32. import org.dromara.system.domain.vo.SysDictDataVo;
  33. import org.dromara.system.domain.vo.TblCarInfoVo;
  34. import org.dromara.system.domain.vo.TblCarScheduleVo;
  35. import org.dromara.system.service.*;
  36. import org.springframework.beans.factory.annotation.Autowired;
  37. import cn.hutool.json.JSONObject;
  38. import org.springframework.stereotype.Component;
  39. import java.io.UnsupportedEncodingException;
  40. import java.nio.charset.Charset;
  41. import java.time.Duration;
  42. import java.util.*;
  43. import static org.dromara.netty.NettyChannelHandlerContextMapCache.ChannelMapCache;
  44. import static org.dromara.netty.NettyChannelHandlerContextMapCache.ChannelMapCache;
  45. @Slf4j
  46. @Component("camelDataUtil")
  47. public class CamelDataUtil {
  48. @Autowired
  49. private CamelContext camelContext;
  50. @Autowired
  51. ITblGpsDataService gpsDataService;
  52. @Autowired
  53. ITblCountDataService countDataService;
  54. @Autowired
  55. ITblCarInfoService tblCarInfoService;
  56. @Autowired
  57. ITblCarScheduleService tblCarScheduleService;
  58. @Autowired
  59. ISysDictDataService sysDictDataService;
  60. private StandardThreadExecutor threadPoolExecutor=new StandardThreadExecutor();
  61. public void SendData(String endrouter,Object payload,String headerkey,Object headervalue){
  62. ProducerTemplate template = camelContext.createProducerTemplate();
  63. template.sendBodyAndHeader(endrouter,payload,headerkey,headervalue);
  64. }
  65. public void processdata(String body, Exchange exchange) throws UnsupportedEncodingException {
  66. Map<String,String> o = exchange.getMessage().getHeader("mqheader", Map.class);
  67. exchange.getMessage().setHeader("CamelPahoOverrideTopic","/dev/"+o.get("devtype")+"/"+o.get("devcode")+"/");
  68. exchange.getMessage().setBody(body.getBytes(Charset.forName("utf8")));
  69. // exchange.getMessage().setBody(body);
  70. }
  71. public void processGpsData(GpsData gpsData){
  72. log.info("body:{}",JSONUtil.toJsonStr(gpsData));
  73. gpsDataService.insertData(gpsData);
  74. //缓存最新数据到redis
  75. RedisUtils.setCacheObject(StringUtils.format("gps_{}", gpsData.getDevicecode()), gpsData);
  76. threadPoolExecutor.execute(new Runnable() {
  77. @Override
  78. public void run() {
  79. TblCarInfoBo carInfoBo = new TblCarInfoBo();
  80. carInfoBo.setDeviceInfos(gpsData.getDevicecode());
  81. List<TblCarInfoVo> carInfoVos = tblCarInfoService.queryList(carInfoBo);
  82. if(carInfoVos.size()>0){
  83. TblCarInfoVo carInfoVo = carInfoVos.get(0);
  84. if(StringUtils.isNotEmpty(carInfoVo.getCarNum())){
  85. //查询车辆信息
  86. TblCarInfoBo carInfoBo1 = new TblCarInfoBo();
  87. carInfoBo1.setCarNum(carInfoVo.getCarNum());
  88. List<TblCarInfoVo> carInfoVos1 = tblCarInfoService.queryList(carInfoBo1);
  89. if(carInfoVos1.size()>0){
  90. // 查询车辆信息
  91. TblCarInfoVo carInfoVo1 = carInfoVos1.get(0);
  92. RedisUtils.setCacheObject(StringUtils.format("gps_{}", carInfoVo1.getId()), gpsData);
  93. TblCarScheduleBo tblCarScheduleBo = new TblCarScheduleBo();
  94. tblCarScheduleBo.setCarNum(carInfoVo1.getCarNum());
  95. Map<String, Object> map = Map.of("scheduleDate", DateUtils.getDate() );
  96. tblCarScheduleBo.setParams(map);
  97. List<TblCarScheduleVo> list = tblCarScheduleService.queryList(tblCarScheduleBo);
  98. if(list.size()>0){
  99. long t0 = 10;
  100. TblCarScheduleVo scheduleVo = null;
  101. for (TblCarScheduleVo vo : list) {
  102. if(vo.getScheduleDate().getTime()-DateUtils.getNowDate().getTime()<0){
  103. if(t0>0){
  104. t0 = vo.getScheduleDate().getTime()-DateUtils.getNowDate().getTime();
  105. scheduleVo = vo;
  106. }
  107. if(t0<vo.getScheduleDate().getTime()-DateUtils.getNowDate().getTime()){
  108. t0 = vo.getScheduleDate().getTime()-DateUtils.getNowDate().getTime();
  109. scheduleVo = vo;
  110. }
  111. }
  112. }
  113. // 查询路线信息
  114. if(scheduleVo!=null){
  115. try{
  116. JSONArray lines = JSONUtil.parseObj(scheduleVo.getPathInfo()).getJSONArray("pathLine");
  117. List<JSONObject> lines1 = new ArrayList<>();
  118. RedisUtils.setCacheObject(StringUtils.format("car_{}_{}_current_station",carInfoVo1.getCarNum(),DateFormatUtils.format( scheduleVo.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS)),"");
  119. for (JSONObject jsonObject : lines.toList(JSONObject.class)) {
  120. double distance = DistanceCalculator.calculateDistance(jsonObject.getStr("location"),StringUtils.format("{},{}", gpsData.getLng(),gpsData.getLat()));
  121. String configdistance = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.car.distance");
  122. if(Double.parseDouble(configdistance)>distance){
  123. String stations = RedisUtils.getCacheObject(StringUtils.format("car_{}_{}_current_station",carInfoVo1.getCarNum(),DateFormatUtils.format( scheduleVo.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS)));
  124. RedisUtils.setCacheObject(StringUtils.format("car_{}_{}_current_station",carInfoVo1.getCarNum(),DateFormatUtils.format( scheduleVo.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS)),stations+","+jsonObject.getStr("stationName"));
  125. //靠近站点 还得计算当前是否跨站点
  126. String stationName = RedisUtils.getCacheObject(StringUtils.format("car_{}_{}_tip",carInfoVo1.getCarNum(),DateFormatUtils.format( scheduleVo.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS) ));
  127. if(stationName!=null && stationName.contains(jsonObject.getStr("stationName"))){
  128. //提报过的不再提报 //离开站记录时间
  129. try {
  130. if (scheduleVo.getExt1() != null) {
  131. //进站点 记录时间
  132. JSONObject datainout = new JSONObject();
  133. datainout = JSONUtil.parseObj(scheduleVo.getExt1());
  134. if (datainout.get(jsonObject.getStr("stationName")) != null) {
  135. JSONObject inout = datainout.getJSONObject(jsonObject.getStr("stationName"));
  136. if (inout.getStr("outtime") == null) {
  137. inout.set("outtime", DateUtil.now());
  138. }
  139. datainout.set(jsonObject.getStr("stationName"), inout);
  140. scheduleVo.setExt1(JSONUtil.toJsonStr(datainout));
  141. TblCarScheduleBo scheduleVo1 = new TblCarScheduleBo();
  142. scheduleVo1.setId(scheduleVo.getId());
  143. scheduleVo1.setExt1(scheduleVo.getExt1());
  144. tblCarScheduleService.updateByBo(scheduleVo1);
  145. }
  146. }
  147. }catch (Exception e){}
  148. }else{
  149. lines1.add(jsonObject);
  150. }
  151. }
  152. }
  153. if(lines1.size()>0){
  154. //先判断是否跨站点
  155. if(lines1.size()>1){
  156. lines1.sort(Comparator.comparingInt((JSONObject o) -> o.getInt("order")));
  157. }
  158. JSONObject jsonObject = lines1.get(0);
  159. String stationName = RedisUtils.getCacheObject(StringUtils.format("car_{}_{}_tip",carInfoVo1.getCarNum(),DateFormatUtils.format( scheduleVo.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS) ));
  160. stationName=stationName==null?"":stationName;
  161. if(!stationName.contains(jsonObject.getStr("stationName"))){
  162. RedisUtils.setCacheObject(StringUtils.format("car_{}_{}_tip",carInfoVo1.getCarNum(), DateFormatUtils.format( scheduleVo.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS) ), stationName+","+jsonObject.getStr("stationName"),Duration.ofSeconds(3600*24));
  163. }
  164. //开始播报
  165. //获取站点设备信息
  166. SysDictDataBo sysDictData = new SysDictDataBo();
  167. sysDictData.setDictLabel(jsonObject.getStr("stationName"));
  168. sysDictData.setDictType("tbl_sites");
  169. List<SysDictDataVo> stations = sysDictDataService.selectDictDataList(sysDictData);
  170. if(stations.size()>0){
  171. try{
  172. //进站点 记录时间
  173. JSONObject datainout = new JSONObject();
  174. if(scheduleVo.getExt1()!=null){
  175. datainout = JSONUtil.parseObj(scheduleVo.getExt1());
  176. }
  177. JSONObject inout = new JSONObject();
  178. inout.set("intime", DateUtil.now());
  179. datainout.set(stations.get(0).getDictLabel(),inout);
  180. scheduleVo.setExt1(JSONUtil.toJsonStr(datainout));
  181. TblCarScheduleBo scheduleVo1 = new TblCarScheduleBo();
  182. scheduleVo1.setId(scheduleVo.getId());
  183. scheduleVo1.setExt1(scheduleVo.getExt1());
  184. tblCarScheduleService.updateByBo(scheduleVo1);
  185. }catch (Exception e){}
  186. //满足条件播报(led or 广播)
  187. String message = StringUtils.format("{}即将到达{},即将到达,请准备接货。", carInfoVo1.getCarNum(),stations.get(0).getDictLabel());
  188. if(StringUtils.isNotEmpty(stations.get(0).getRemark())){
  189. List<JSONObject> devicedatas = JSONUtil.parseArray( stations.get(0).getRemark()).toList(JSONObject.class);
  190. for (JSONObject i :devicedatas) {
  191. if(i.getStr("type").equals("led")){
  192. MessageUtils.sendLed(i.getStr("code"), message);
  193. }
  194. if(i.getStr("type").equals("tts")){
  195. MessageUtils.sendTTs(i.getStr("code"), message);
  196. }
  197. }
  198. }
  199. }
  200. }else{
  201. RedisUtils.setCacheObject(StringUtils.format("car_{}_{}_current_station",carInfoVo1.getCarNum(),DateFormatUtils.format( scheduleVo.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS)),"");
  202. }
  203. }catch (Exception e){
  204. log.error("---------------------");
  205. log.error(e.getMessage());
  206. log.error("---------------------");
  207. }
  208. }
  209. }
  210. }
  211. }
  212. }
  213. }
  214. });
  215. }
  216. public void ReciveData(String body, Exchange exchange){
  217. if(exchange.getMessage().getHeaders().get("CamelMqttTopic").toString().contains("gps")){
  218. String devicecode = exchange.getMessage().getHeaders().get("CamelMqttTopic").toString().split("/")[3];
  219. GpsData gpsData = new GpsData();
  220. gpsData.setDevicecode(devicecode);
  221. gpsData.setLat(JSONUtil.parseObj(body).getDouble("LAT"));
  222. gpsData.setLng(JSONUtil.parseObj(body).getDouble("LNG"));
  223. gpsData.setAlt(JSONUtil.parseObj(body).getDouble("ALT"));
  224. gpsData.setSpeed(JSONUtil.parseObj(body).getDouble("SPD"));
  225. if(JSONUtil.parseObj(body).getDouble("SPD")>0){
  226. processGpsData(gpsData);
  227. }
  228. }
  229. log.info("body:{}",body);
  230. }
  231. public void ReciveTcpData(String body, Exchange exchange) throws UnsupportedEncodingException {
  232. StringBuilder countdatastr= new StringBuilder("");
  233. JSONArray data= JSONUtil.parseArray(body);
  234. for (int i = 0; i < data.size(); i++) {
  235. if( data.get(i) instanceof Integer){
  236. countdatastr.append((char)(((Integer) data.get(i)).byteValue()&0xff));
  237. }
  238. }
  239. if(StrUtil.isNotEmpty(countdatastr.toString())){
  240. log.info("body:{}",countdatastr);
  241. JSONObject countdata = JsonUtils.parseObject(countdatastr.toString(), JSONObject.class);
  242. String sn = countdata.getStr("sn");
  243. String type = countdata.getStr("type");
  244. Long time = countdata.getLong("time");
  245. Integer in = 0;
  246. Integer out = 0;
  247. Long iCreatedTime = 0L;
  248. if(type.equals("count")){
  249. //获取数据in out
  250. JSONArray inoutarry = ((JSONObject)(countdata.getJSONArray("data").get(0))).getJSONArray("count");
  251. for (int i = 0; i < inoutarry.size(); i++) {
  252. if(((JSONObject)inoutarry.get(i)).getStr("name").equals("d1")){
  253. in = ((JSONObject)inoutarry.get(i)).getInt("in");
  254. out = ((JSONObject)inoutarry.get(i)).getInt("out");
  255. break;
  256. }
  257. }
  258. iCreatedTime = ((JSONObject)(countdata.getJSONArray("data").get(0))).getLong("iCreatedTime");
  259. if(iCreatedTime*1000>DateUtil.current()-24*3600*1000 && iCreatedTime*1000<DateUtil.current()+24*3600*1000){
  260. //正确的时间
  261. CountData countData = new CountData();
  262. countData.setIncount(in);
  263. countData.setOutcount(out);
  264. countData.setDevicecode(sn);
  265. countData.setTslong(iCreatedTime*1000);
  266. countDataService.insertData(countData);
  267. }else{
  268. log.error("{}:时间错误",iCreatedTime);
  269. }
  270. //存储数据
  271. // log.info("{},{},{},{},{}",sn,type,in,out,iCreatedTime);
  272. }
  273. //组织返回数据
  274. JSONObject result = new JSONObject();
  275. result.put( "sn" , sn) ;
  276. result.put("type", type) ;
  277. if(type.equals("heart")){
  278. JSONObject sub = new JSONObject() ;
  279. sub.put("time", time) ;
  280. result.put("data", sub ) ;
  281. }else{
  282. result.put("time", time ) ;
  283. }
  284. NettyChannelHandlerContext ctx = ChannelMapCache.get(((ChannelHandlerContext)exchange.getIn().getHeader("CamelNettyChannelHandlerContext")).channel().toString());
  285. ByteBuf buf = Unpooled.copiedBuffer(JsonUtils.toJsonString(result).getBytes(CharsetUtil.UTF_8));
  286. ctx.getChannelHandlerContext().writeAndFlush(buf);
  287. }
  288. }
  289. // public static void main(String[] args) {
  290. // String ss = "{\"pathLine\": [{\"order\": 1, \"location\": \"119.807462,26.958413\", \"planInTime\": \"00:15:00\", \"planOutTime\": \"01:15:00\", \"stationName\": \"松罗乡\"}, {\"order\": 2, \"location\": \"119.723653,26.841206\", \"planInTime\": \"00:30:00\", \"planOutTime\": \"01:15:00\", \"stationName\": \"福安客运站\"}, {\"order\": 3, \"location\": \"119.852881,26.817088\", \"planInTime\": \"01:15:00\", \"planOutTime\": \"04:15:00\", \"stationName\": \"姚澳村\"}], \"driverInfo\": 2, \"attendantInfo\": \"1763485590079639554\"}";
  291. // JSONArray lines = JSONUtil.parseObj(ss).getJSONArray("pathLine");
  292. // List<JSONObject> lines1 = lines.toList(JSONObject.class);
  293. // lines1.sort(Comparator.comparingInt((JSONObject o) -> o.getInt("order")));
  294. // System.out.println(lines1.get(0).toStringPretty());
  295. // }
  296. }