UserHandler.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. package com.js.kbt.socket;
  2. import java.math.BigDecimal;
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6. import java.util.List;
  7. import javax.annotation.Resource;
  8. import org.apache.log4j.Logger;
  9. import org.springframework.stereotype.Service;
  10. import com.alibaba.fastjson.JSONObject;
  11. import com.aliyuncs.http.HttpRequest;
  12. import com.js.kbt.mapper.MouldHistoryMapper;
  13. import com.js.kbt.mapper.MouldHistoryTimeMapper;
  14. import com.js.kbt.mapper.TbFactoryMapper;
  15. import com.js.kbt.mapper.TbMouldEquipmentMapper;
  16. import com.js.kbt.mapper.TbMouldMapper;
  17. import com.js.kbt.model.MouldHistory;
  18. import com.js.kbt.model.MouldHistoryTime;
  19. import com.js.kbt.model.MouldHistoryTimeExample;
  20. import com.js.kbt.model.TbMould;
  21. import com.js.kbt.model.TbMouldEquipment;
  22. import com.js.kbt.model.TbMouldEquipmentExample;
  23. import com.js.kbt.model.TbMouldExample;
  24. import com.js.kbt.util.MathUtil;
  25. import io.netty.buffer.ByteBuf;
  26. import io.netty.buffer.Unpooled;
  27. import io.netty.channel.ChannelHandlerContext;
  28. import io.netty.channel.SimpleChannelInboundHandler;
  29. import io.netty.handler.timeout.IdleState;
  30. import io.netty.handler.timeout.IdleStateEvent;
  31. @Service("userHandler")
  32. public class UserHandler extends SimpleChannelInboundHandler<String> {
  33. private static final Logger logger = Logger.getLogger(UserHandler.class);
  34. private ChannelHandlerContext ctx;
  35. @Resource
  36. private MouldHistoryMapper mouldHistoryMapper;
  37. @Resource
  38. private MouldHistoryTimeMapper mouldHistoryTimeMapper;
  39. @Resource
  40. private TbMouldMapper tbMouldMapper;
  41. @Resource
  42. private TbMouldEquipmentMapper tbMouldEquipmentMapper;
  43. @Resource
  44. private TbFactoryMapper tbFactoryMapper;
  45. @Override
  46. protected void channelRead0(ChannelHandlerContext arg0, String arg1)
  47. {
  48. System.out.println("收到==="+arg1+"\n");
  49. String ret = processMsg(arg1);
  50. // sendMsg(ret);
  51. }
  52. private String processMsg(String input) {
  53. String ret = "FA AF 00 07 02 1e 78 1e 50 00 3C";
  54. logger.info("=====接收到======"+input);
  55. if (!input.startsWith("FAAF")) {
  56. logger.info("非云模盒消息,不处理");
  57. return ret;
  58. }
  59. MouldHistory item = new MouldHistory();
  60. //抽取手机号码
  61. String mobilePart = input.substring(4*2, 15*2);
  62. System.out.println("原始mobile="+mobilePart);
  63. String mobile = getStringFromHexStr(mobilePart);
  64. System.out.println("手机号码为"+mobile);
  65. item.setSim(mobile);
  66. //获取设备编码15-24
  67. String deviceNumPart = input.substring(15*2, 25*2);
  68. String deviceNum = getStringFromHexStr(deviceNumPart);
  69. System.out.println("设备No="+deviceNum);
  70. item.setEquipmentNo(deviceNum);
  71. //软件版本号25
  72. String version = input.substring(25*2, 26*2);
  73. System.out.println("软件版本号="+version);
  74. item.setVersion(version);
  75. String status = input.substring(26*2, 27*2);
  76. System.out.println("工作状态="+status);
  77. item.setStatus(Integer.decode("0x"+status).toString());
  78. //经度27-37
  79. String longitude = getStringFromHexStr(input.substring(27*2, 38*2));
  80. System.out.println("经度="+longitude);
  81. item.setLng(longitude);
  82. //38-47纬度以 N 开头
  83. String latitude = getStringFromHexStr(input.substring(38*2, 48*2));
  84. System.out.println("纬度="+latitude);
  85. item.setLat(latitude);
  86. System.out.println("==lac"+reverseParseHex(input.substring(48*2, 50*2)));
  87. System.out.println("==ci"+reverseParseHex(input.substring(50*2, 52*2)));
  88. item.setGprsLac(""+reverseParseHex(input.substring(48*2, 50*2)));
  89. item.setGprsCi(""+reverseParseHex(input.substring(50*2, 52*2)));
  90. item.setWifiBbsid(input.substring(52*2, 58*2));
  91. String temp = "0x"+input.substring(58*2, 59*2);
  92. System.out.println(temp);
  93. int i = Integer.decode(temp);
  94. System.out.println(i);
  95. item.setTemperature(i);
  96. item.setBattery(Integer.decode("0x"+input.substring(59*2, 60*2)));
  97. item.setSig2g(Integer.decode("0x"+input.substring(60*2, 61*2)));
  98. item.setSigNb(Integer.decode("0x"+input.substring(61*2, 62*2)));
  99. item.setSigWifi(Integer.decode("0x"+input.substring(62*2, 63*2)));
  100. item.setExt0(""+Integer.decode("0x"+input.substring(63*2, 64*2)));
  101. item.setAlarm(Integer.decode("0x"+input.substring(64*2, 65*2)));
  102. String str = input.substring(65*2, 69*2);
  103. item.setRunCnt(reverseParseHex(str));
  104. //根据基站lac和ci获取经纬度
  105. String api = "http://api.cellocation.com:81/cell/?mcc=460&mnc=0&lac="+item.getGprsLac()+"&ci="+item.getGprsCi()+"&output=json";
  106. String resp = com.js.kbt.util.HttpRequest.sendGet(api, null);
  107. JSONObject json = JSONObject.parseObject(resp);
  108. if (json.getInteger("errcode") == 0) {
  109. item.setLng(json.getDouble("lon") + "");
  110. item.setLat(json.getDouble("lat") + "");
  111. } else {
  112. logger.error("调用基站解析平台出错: " + resp);
  113. }
  114. String crcStr = input.substring(input.length() - 4);
  115. item.setCrcCode(""+reverseParseHex(crcStr));
  116. //存入数据库
  117. mouldHistoryMapper.insertSelective(item);
  118. //模具开合记录
  119. int cnt = item.getRunCnt();
  120. int start = 69;
  121. logger.info("累计开合模次数="+cnt);
  122. int end = input.length() - 4; //最后2位 0xXX,0xXX ,是CRC校验位
  123. logger.info("时间信息=="+input.substring(start*2, end));
  124. if (end - start*2 >= 24) {//时间最少6位,1位显示0x00,开合算两个时间,所以是6*2*2=24
  125. //本次运行周期内的开合模次数
  126. int periodCnt = (end-start*2)/24;
  127. logger.info("本次开合模次数=="+periodCnt);
  128. for (int pos=0; pos<periodCnt; pos++ ) {
  129. //合模时间
  130. MouldHistoryTime time = new MouldHistoryTime();
  131. time.setHistoryId(item.getId());
  132. time.setEquipmentNo(item.getEquipmentNo());
  133. time.setSeq(pos + 1);
  134. Date closeTime = parseDate(input, start, pos, 0);
  135. time.setCloseTime(closeTime);
  136. //开模时间
  137. Date openTime = parseDate(input, start, pos, 6);
  138. time.setOpenTime(openTime);
  139. int timeCost = (int) (openTime.getTime() - closeTime.getTime());
  140. time.setTimeCost(timeCost);
  141. mouldHistoryTimeMapper.insertSelective(time);
  142. }
  143. } else {
  144. logger.info("本次开合模次数==0");
  145. }
  146. //统计该模盒的平均开合周期
  147. MouldHistoryTimeExample exp = new MouldHistoryTimeExample();
  148. exp.createCriteria().andEquipmentNoEqualTo(item.getEquipmentNo());
  149. List<MouldHistoryTime> list = mouldHistoryTimeMapper.selectByExample(exp);
  150. int avgTime = 0;
  151. int totalTime = 0;
  152. for (MouldHistoryTime t : list) {
  153. totalTime += t.getTimeCost();
  154. }
  155. if (list.size() == 0) {
  156. avgTime = 0;
  157. } else {
  158. avgTime = totalTime / list.size();
  159. }
  160. handleModLogic(item, avgTime);
  161. return ret;
  162. }
  163. private void handleModLogic(MouldHistory item, int avgTime) {
  164. TbMouldEquipmentExample meqExp = new TbMouldEquipmentExample();
  165. meqExp.createCriteria().andEquipmentNoEqualTo(item.getEquipmentNo());
  166. if (tbMouldEquipmentMapper.countByExample(meqExp) > 0) {
  167. TbMouldEquipment me = tbMouldEquipmentMapper.selectByExample(meqExp).get(0);
  168. me.setHillNumber(item.getBattery()+"%");
  169. if (item.getLng() != null) {
  170. me.setLng(Double.parseDouble(item.getLng()));
  171. me.setLat(Double.parseDouble(item.getLat()));
  172. }
  173. me.setTemperature(item.getTemperature());
  174. tbMouldEquipmentMapper.updateByPrimaryKeySelective(me);
  175. TbMouldExample tExp = new TbMouldExample();
  176. tExp.setOrderByClause("id desc limit 1");
  177. tExp.createCriteria().andEquipmentIdEqualTo(me.getId());
  178. if (tbMouldMapper.countByExample(tExp) > 0) {
  179. TbMould tm = tbMouldMapper.selectByExample(tExp).get(0);
  180. tm.setState(item.getStatus());
  181. tm.setRunTimes(tm.getRunTimes() + item.getRunCnt());
  182. //处理每模平均周期(单位秒)
  183. BigDecimal bd = new BigDecimal(avgTime*1.00/1000);
  184. tm.setOcCycle(bd);
  185. tbMouldMapper.updateByPrimaryKeySelective(tm);
  186. //处理报警
  187. if (item.getAlarm() > 0) {
  188. /**
  189. * 无报警 0;
  190. 低电量报警 1;
  191. 温度过热 2;
  192. 安装被拆 8。
  193. */
  194. logger.info("设备报警啦:"+item.getAlarm());
  195. }
  196. }
  197. }
  198. }
  199. /**
  200. * 低位在前的16进制解析
  201. * @param rHex
  202. * @return
  203. */
  204. public static int reverseParseHex(String rHex) {
  205. int size = rHex.length()/2;
  206. StringBuilder sb = new StringBuilder();
  207. for (int i=0;i<size; i++) {
  208. sb.append(rHex.substring((size - i -1)*2, (size - i)*2));
  209. }
  210. String str = sb.toString();
  211. return Integer.parseInt(str, 16);
  212. }
  213. private static Date parseDate(String input, int start, int pos, int dateStartPos) {
  214. String year = input.substring((start+pos*6 + dateStartPos)*2, (start+pos*6 + 1 + dateStartPos)*2);
  215. String month = input.substring((start+pos*6+1 + dateStartPos)*2, (start+pos*6 + 2 + dateStartPos)*2);
  216. String day = input.substring((start+pos*6+2 + dateStartPos)*2, (start+pos*6 + 3 + dateStartPos)*2);
  217. String hh = input.substring((start+pos*6+3 + dateStartPos)*2, (start+pos*6 + 4 + dateStartPos)*2);
  218. String mm = input.substring((start+pos*6+4 + dateStartPos)*2, (start+pos*6 + 5 + dateStartPos)*2);
  219. String ss = input.substring((start+pos*6+5 + dateStartPos)*2, (start+pos*6 + 6 + dateStartPos)*2);
  220. StringBuilder sb = new StringBuilder();
  221. int yearInt = Integer.parseInt(year, 16);
  222. if (yearInt == 0) {
  223. sb.append("2019-01-01");
  224. } else {
  225. sb.append(yearInt < 100?"20":"2");
  226. sb.append(yearInt).append("-");
  227. int monthInt = Integer.parseInt(month, 16);
  228. sb.append(monthInt<10?"0":"").append(monthInt).append("-");
  229. int dayInt = Integer.parseInt(day, 16);
  230. sb.append(dayInt<10?"0":"").append(dayInt);
  231. }
  232. Date parseDate = null;
  233. try {
  234. parseDate = new SimpleDateFormat("yyyy-MM-dd").parse(sb.toString());
  235. parseDate.setHours(Integer.parseInt(hh, 16));
  236. parseDate.setMinutes(Integer.parseInt(mm, 16));
  237. parseDate.setSeconds(Integer.parseInt(ss, 16));
  238. } catch (ParseException e) {
  239. e.printStackTrace();
  240. }
  241. return parseDate;
  242. }
  243. private String getStringFromHexStr(String hexStr) {
  244. StringBuilder sb = new StringBuilder();
  245. for (int i=0;i<hexStr.length()/2; i++) {
  246. String str = "0x"+hexStr.substring(i*2, i*2 + 2);
  247. int intVal = Integer.decode(str).intValue();
  248. char c = (char)intVal;
  249. sb.append(c);
  250. }
  251. return sb.toString();
  252. }
  253. public void close() {
  254. ctx.close();
  255. }
  256. public void sendMsg(String hexString) {
  257. System.out.println("发送消息=="+hexString);
  258. byte[] buffer = hexStrToBinaryStr(hexString);
  259. ByteBuf bf = Unpooled.buffer(hexString.length()/2);
  260. bf.writeBytes(buffer);
  261. ctx.writeAndFlush(bf);
  262. // ctx.close();
  263. }
  264. /**
  265. * channel被激活时调用
  266. */
  267. @Override
  268. public void channelActive(ChannelHandlerContext ctx){
  269. // TODO Auto-generated method stub
  270. this.ctx = ctx;
  271. System.out.println("==========Active========="+ctx.channel().localAddress().toString()+", connection num="+HelloServer.deviceMap.size());
  272. }
  273. @Override
  274. public void channelInactive(ChannelHandlerContext ctx) throws Exception {
  275. super.channelInactive(ctx);
  276. System.out.println("==========Inactive=========");
  277. }
  278. @Override
  279. public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
  280. // TODO Auto-generated method stub
  281. super.handlerRemoved(ctx);
  282. System.out.println("[YunSu]handlerRemoved=掉线了===");
  283. }
  284. @Override
  285. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
  286. throws Exception {
  287. // TODO Auto-generated method stub
  288. super.exceptionCaught(ctx, cause);
  289. System.out.println("我捕捉到异常信息了");
  290. }
  291. @Override
  292. public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
  293. throws Exception {
  294. if (evt instanceof IdleStateEvent) {
  295. IdleStateEvent event = (IdleStateEvent) evt;
  296. if (event.state().equals(IdleState.READER_IDLE)) {
  297. } else if (event.state().equals(IdleState.WRITER_IDLE)) {
  298. // System.out.println("WRITER_IDLE=="+userInfo.getWxName());
  299. // logger.debug(ctx.channel().remoteAddress().toString()+ "WRITER_IDLE");
  300. // 超时关闭channel
  301. // ctx.close();
  302. } else if (event.state().equals(IdleState.ALL_IDLE)) {
  303. // 发送心跳
  304. ctx.channel().writeAndFlush("$&_".toString());
  305. }
  306. }
  307. // super.userEventTriggered(ctx, evt);
  308. }
  309. /**
  310. * 将十六进制的字符串转换成字节数组
  311. *
  312. * @param hexString
  313. * @return
  314. */
  315. public static byte[] hexStrToBinaryStr(String hexString) {
  316. if (hexString == null || "".contentEquals(hexString)) {
  317. return null;
  318. }
  319. hexString = hexString.replaceAll(" ", "");
  320. int len = hexString.length();
  321. int index = 0;
  322. byte[] bytes = new byte[len / 2];
  323. while (index < len) {
  324. String sub = hexString.substring(index, index + 2);
  325. bytes[index/2] = (byte)Integer.parseInt(sub,16);
  326. index += 2;
  327. }
  328. return bytes;
  329. }
  330. /**
  331. * 将字节数组转换成十六进制的字符串
  332. *
  333. * @return
  334. */
  335. public static String BinaryToHexString(byte[] bytes) {
  336. String hexStr = "0123456789ABCDEF";
  337. String result = "";
  338. String hex = "";
  339. for (byte b : bytes) {
  340. hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 4));
  341. hex += String.valueOf(hexStr.charAt(b & 0x0F));
  342. result += hex + " ";
  343. }
  344. return result;
  345. }
  346. public static void main(String[] args) {
  347. // String str = "1F51";
  348. String input = "FAAF530000000000000000000000003137333030303239343310010000000000000000000000000000000000000000001F51E85F00000000000045004A54000100110000001308160F171F1308160F2D188FCA";
  349. // String temp = "0x"+str;
  350. // int i = Integer.decode(temp);
  351. // System.out.println(i);
  352. // int p = reverseParseHex(str);
  353. // System.out.println(p);
  354. // int start = 69;
  355. // System.out.println(str.substring(69*2));
  356. // Date d = parseDate(str, start, 0, 0);
  357. // System.out.println(d.toGMTString());
  358. int start = 69;
  359. int end = input.length() - 4; //最后2位 0xXX,0xXX ,是CRC校验位
  360. logger.info("时间信息=="+input.substring(start*2, end));
  361. if (end - start*2 >= 24) {//时间最少6位,1位显示0x00,开合算两个时间,所以是6*2*2=24
  362. //本次运行周期内的开合模次数
  363. int periodCnt = (end-start*2)/24;
  364. logger.info("本次开合模次数=="+periodCnt);
  365. for (int pos=0; pos<periodCnt; pos++ ) {
  366. //合模时间
  367. MouldHistoryTime time = new MouldHistoryTime();
  368. time.setSeq(pos + 1);
  369. Date closeTime = parseDate(input, start, pos, 0);
  370. time.setCloseTime(closeTime);
  371. //开模时间
  372. Date openTime = parseDate(input, start, pos, 6);
  373. time.setOpenTime(openTime);
  374. int timeCost = (int) (openTime.getTime() - closeTime.getTime());
  375. time.setTimeCost(timeCost);
  376. }
  377. } else {
  378. logger.info("本次开合模次数==0");
  379. }
  380. }
  381. }