EnvInputServerHandler.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. package com.huimv.env.input.server;
  2. import cn.hutool.core.util.ObjectUtil;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5. import com.huimv.env.common.entity.EnvFeed;
  6. import com.huimv.env.common.service.IEnvElectricityService;
  7. import com.huimv.env.common.service.IEnvFeedService;
  8. import com.huimv.env.common.service.IEnvWaterService;
  9. import com.huimv.env.input.utils.ModBusUtils;
  10. import io.netty.buffer.ByteBuf;
  11. import io.netty.buffer.Unpooled;
  12. import io.netty.channel.*;
  13. import lombok.extern.slf4j.Slf4j;
  14. import org.springframework.beans.factory.annotation.Autowired;
  15. import org.springframework.stereotype.Component;
  16. import java.io.IOException;
  17. import java.math.BigDecimal;
  18. import java.text.ParseException;
  19. import java.util.Date;
  20. import java.util.HashMap;
  21. import java.util.Map;
  22. import java.util.regex.Matcher;
  23. import java.util.regex.Pattern;
  24. import static com.huimv.env.input.utils.ModBusUtils.hexStr2Bytes;
  25. /**
  26. * @Project : huimv.shiwan
  27. * @Package : com.huimv.biosafety.uface.controller
  28. * @Description : TODO
  29. * @Version : 1.0
  30. * @Author : ZhuoNing
  31. * @Create : 2020-12-25
  32. **/
  33. @ChannelHandler.Sharable
  34. @Component
  35. @Slf4j
  36. public class EnvInputServerHandler extends ChannelInboundHandlerAdapter {
  37. private StringBuilder askTextSb = null;
  38. @Autowired
  39. private IEnvFeedService envFeedService;
  40. //
  41. public void appendClientAsk(String text) {
  42. if (this.askTextSb == null) {
  43. askTextSb = new StringBuilder();
  44. }
  45. askTextSb.append(text);
  46. }
  47. private static long LAST_NOW = System.currentTimeMillis();
  48. @Override
  49. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  50. Channel channel = ctx.channel();
  51. ByteBuf byteBuf = (ByteBuf) msg;
  52. byte[] bytes = new byte[byteBuf.readableBytes()];
  53. byteBuf.readBytes(bytes);
  54. String str = ModBusUtils.bytes2HexString(bytes);
  55. // System.out.println(str);
  56. long now = System.currentTimeMillis();
  57. long time = 5 * 60 * 1000;
  58. if ((LAST_NOW + time) < now){
  59. //这里写保存逻辑
  60. try {
  61. String cmd = saveWeight(str);
  62. System.out.println(cmd);
  63. LAST_NOW = now;
  64. }catch (Exception e){
  65. System.out.println(e);
  66. }
  67. }
  68. }
  69. private String saveWeight(String str) {
  70. String[] split = str.split(" ");
  71. //FF 11 12 C0 C0
  72. StringBuilder stringBuilder = new StringBuilder();
  73. if (isNumeric(split[4])){
  74. stringBuilder.append(split[4]);
  75. }
  76. if (isNumeric(split[3])){
  77. stringBuilder.append(split[3]);
  78. }
  79. if (isNumeric(split[2])) {
  80. stringBuilder.append(split[2]);
  81. }
  82. //当前值
  83. BigDecimal bigDecimal = new BigDecimal(stringBuilder.toString());
  84. EnvFeed id = envFeedService.getOne(new QueryWrapper<EnvFeed>().orderByDesc("id").last("limit 1"));
  85. BigDecimal lastBigDecimal = new BigDecimal(0);
  86. if (ObjectUtil.isNotEmpty(id)){
  87. //上一次的值
  88. lastBigDecimal = id.getOriginalValue();
  89. }
  90. BigDecimal subtract1 = lastBigDecimal.subtract(bigDecimal);
  91. if (subtract1.compareTo(new BigDecimal(1000)) >0 || subtract1.compareTo(new BigDecimal(-1000))<0){
  92. return "差值为" +subtract1 +",舍弃";
  93. }
  94. EnvFeed envFeed = new EnvFeed();
  95. envFeed.setFarmId(27);
  96. envFeed.setUpdateTime(new Date());
  97. envFeed.setOriginalValue(bigDecimal);
  98. if(lastBigDecimal.compareTo(bigDecimal) > 0){
  99. BigDecimal subtract = lastBigDecimal.subtract(bigDecimal).divide(new BigDecimal(1000),3);
  100. envFeed.setHandleValue(subtract);
  101. }else {
  102. envFeed.setHandleValue(new BigDecimal(0));
  103. }
  104. envFeedService.save(envFeed);
  105. return stringBuilder.toString();
  106. }
  107. public static boolean isNumeric(String str) {
  108. return str.matches("\\d+");
  109. }
  110. /* @Override
  111. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  112. Channel channel = ctx.channel();
  113. ByteBuf byteBuf = (ByteBuf) msg;
  114. byte[] bytes = new byte[byteBuf.readableBytes()];
  115. byteBuf.readBytes(bytes);
  116. String str = ModBusUtils.bytes2HexString(bytes);
  117. System.out.println("收到的数据:"+str);
  118. String cmd = saveWaterAndEle(str);
  119. Thread.sleep(5*1000);
  120. System.out.println(cmd);
  121. channel.writeAndFlush(Unpooled.copiedBuffer(hexStr2Bytes(cmd)));
  122. super.channelRead(ctx, msg);
  123. }
  124. private String saveWaterAndEle(String str) {
  125. String[] s = str.split(" ");
  126. //读水表
  127. String cmd ="1D 03 00 00 00 02 C6 57";
  128. //读电表
  129. // String cmd ="1C 04 01 00 00 02 73 BA";
  130. if (s.length>10 || s.length<7){
  131. return cmd;
  132. }
  133. String val = s[3]+s[4]+s[5]+s[6];
  134. System.out.println("val=" +val);
  135. Date now = new Date();
  136. //水表
  137. if (str.startsWith("1D 03")){
  138. try {
  139. System.out.println("水表");
  140. int waterOrigValue = Integer.parseInt(val, 16);
  141. BigDecimal bigDecimal1 = new BigDecimal(waterOrigValue);
  142. BigDecimal bigDecimal = new BigDecimal(0);
  143. if (!bigDecimal1.equals(0)){
  144. bigDecimal = bigDecimal1.divide(new BigDecimal(100),1,BigDecimal.ROUND_HALF_UP);
  145. }
  146. EnvWater oldEnvWater = envWaterService.getOne(new QueryWrapper<EnvWater>().orderByDesc("id").last("limit 1"));
  147. BigDecimal originalValue = oldEnvWater.getOriginalValue();
  148. EnvWater envWater = new EnvWater();
  149. envWater.setOriginalValue(bigDecimal);
  150. int i = bigDecimal.compareTo(originalValue);
  151. if (ObjectUtil.isNotEmpty(oldEnvWater) && i >= 0) {
  152. envWater.setHandleValue(bigDecimal.subtract(originalValue));
  153. }else {
  154. envWater.setHandleValue(bigDecimal);
  155. }
  156. envWater.setUpdateTime(now);
  157. envWater.setFarmId(27);
  158. envWaterService.save(envWater);
  159. cmd = "1C 04 01 00 00 02 73 BA";
  160. }catch (Exception e){
  161. System.out.println(e);
  162. }
  163. }
  164. //电表
  165. if (str.startsWith("1C 04")){
  166. try {
  167. System.out.println("电表");
  168. int eleOrigValue = Integer.parseInt(val, 16);
  169. Float f = Float.intBitsToFloat(eleOrigValue);
  170. BigDecimal bigDecimal = new BigDecimal(f);
  171. EnvElectricity oldEnvWater = envElectricityService.getOne(new QueryWrapper<EnvElectricity>().orderByDesc("id").last("limit 1"));
  172. BigDecimal originalValue = oldEnvWater.getOriginalValue();
  173. EnvElectricity envElectricity = new EnvElectricity();
  174. envElectricity.setOriginalValue(bigDecimal);
  175. int i = bigDecimal.compareTo(originalValue);
  176. if (ObjectUtil.isNotEmpty(oldEnvWater) && i>=0){
  177. envElectricity.setHandleValue(bigDecimal.subtract(originalValue));
  178. }else {
  179. envElectricity.setHandleValue(bigDecimal.subtract(bigDecimal));
  180. }
  181. envElectricity.setUpdateTime(now);
  182. envElectricity.setFarmId(27);
  183. envElectricityService.save(envElectricity);
  184. }catch (Exception e){
  185. System.out.println(e);
  186. }
  187. }
  188. return cmd;
  189. }
  190. */
  191. private Integer countWeight(String[] s) {
  192. int count = 48;
  193. return (Integer.parseInt(s[8], 16) -count)
  194. +((Integer.parseInt(s[9], 16) -count) * 16)
  195. +((Integer.parseInt(s[10], 16) -count) * 256)
  196. +((Integer.parseInt(s[11], 16) -count) * 4096)
  197. +((Integer.parseInt(s[12], 16) -count) * 6556);
  198. }
  199. @Override
  200. public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
  201. // if (true){
  202. // ctx.writeAndFlush(Unpooled.copiedBuffer(new byte[]{1, 2, 3}));
  203. // }
  204. // if (askTextSb.toString().indexOf("end") != -1) {
  205. // // {处理客户端消息}
  206. // handleClientAskCmd(askTextSb.toString(), ctx);
  207. // //清空重置;
  208. // askTextSb.delete(0, askTextSb.length());
  209. // }
  210. }
  211. @Override
  212. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  213. if (cause.getMessage().indexOf("Connection reset") != -1) {
  214. log.info("相关采集器设备正在重启:" + cause.toString());
  215. }
  216. // cause.printStackTrace();
  217. ctx.close();
  218. }
  219. /**
  220. * @Method : handleClientAskCmd
  221. * @Description : 处理请求小心
  222. * @Params : [clientAskText, ctx]
  223. * @Return : void
  224. * @Author : ZhuoNing
  225. * @Date : 2022/3/28
  226. * @Time : 17:36
  227. */
  228. private void handleClientAskCmd(String clientAskText, ChannelHandlerContext ctx) throws ParseException, IOException {
  229. clientAskText = clientAskText.replaceAll("\r", "").replaceAll("\n", "");
  230. //{处理非正常命令}
  231. // int countPlus = regexUtil.countPlus(clientAskText);
  232. // if (countPlus < 4) {
  233. // System.out.println("当前数据为不完整数据,故丢弃.>>" + clientAskText);
  234. // } else {
  235. //--处理客户端请求数据
  236. //{拆分粘包数据}
  237. JSONArray askJa = parseAskCmdPackage(clientAskText);
  238. for (int a = 0; a < askJa.size(); a++) {
  239. String askText = askJa.getString(a);
  240. //{处理请求命令}
  241. askCmdActuator(askText, ctx);
  242. }
  243. // }
  244. }
  245. /**
  246. * @Method : askCmdActuator
  247. * @Description :
  248. * @Params : [askText, ctx]
  249. * @Return : void
  250. * @Author : ZhuoNing
  251. * @Date : 2022/3/23
  252. * @Time : 18:08
  253. */
  254. private void askCmdActuator(String askText, ChannelHandlerContext ctx) throws ParseException, IOException {
  255. System.out.println("======>接收设备请求:" + askText);
  256. String[] dataArray = askText.split("\\+");
  257. String cmdHeader = dataArray[0];
  258. if (!cmdHeader.trim().equalsIgnoreCase("hm")) {
  259. log.info("当前命令是非hm命令[" + askText + "]");
  260. return;
  261. }
  262. //芯片id/设备编码
  263. String idCode = dataArray[1];
  264. String cmd = dataArray[2];
  265. Map map = new HashMap();
  266. map.put("askText", askText);
  267. switch (cmd) {
  268. case "1":
  269. //获取远程设备编码
  270. getDeviceCode(askText, idCode, ctx);
  271. break;
  272. case "2":
  273. //同步时间
  274. getServerTime(askText, idCode, ctx);
  275. break;
  276. default:
  277. System.out.println("==>未知命令");
  278. log.error(">>当前数据为非法数据-未知命令>>" + askText);
  279. }
  280. }
  281. //时间同步请求
  282. private void getServerTime(String askText, String deviceCode, ChannelHandlerContext ctx) throws ParseException {
  283. System.out.println("==>时间同步请求:" + askText);
  284. // if (!cmdProService.isEffectiveDevice(deviceCode)) {
  285. // System.out.println("##时间同步请求-未注册设备 idCode=" + deviceCode);
  286. // return;
  287. // }
  288. String answerText = "hm+2+" + "+0+4+end";
  289. // log.info(">>时间同步请求-应答数据>>" + answerText);
  290. answerCmd(answerText, ctx);
  291. }
  292. //获取远程设备编码
  293. private void getDeviceCode(String askText, String idCode, ChannelHandlerContext ctx) {
  294. System.out.println("==>获取远程设备编码请求:" + askText.trim());
  295. //{读取设备编码}
  296. // String deviceCode = cmdProService.getDeviceCodeByChipId(idCode);
  297. // log.info("获取远程设备编码请求,芯片id>>" + idCode + " ,deviceCode>>" + deviceCode);
  298. // if (deviceCode == null) {
  299. // log.error("该设备未注册,已舍弃请求.");
  300. // return;
  301. // }
  302. // String answerText = "hm+1+0+" + deviceCode + "+123+8+end";
  303. // log.info("<<获取远程设备编码请求-应答数据:" + answerText);
  304. //{应答指令}
  305. // answerCmd(answerText, ctx);
  306. }
  307. //应答
  308. public void answerCmd(String answerText, ChannelHandlerContext ctx) {
  309. ctx.writeAndFlush(Unpooled.copiedBuffer(answerText.getBytes()));
  310. }
  311. //检查无效耳标
  312. public boolean checkValidEarmark(String earmark) {
  313. if (earmark.trim().equalsIgnoreCase("ffffffffffffffff") || earmark.trim().equalsIgnoreCase("0000000000000000")) {
  314. return true;
  315. } else {
  316. return false;
  317. }
  318. }
  319. //拆分粘包数据
  320. public JSONArray parseAskCmdPackage(String text) {
  321. String key = "end";
  322. Pattern pattern = Pattern.compile(key);
  323. Matcher matcher = pattern.matcher(text);
  324. int count = 0;
  325. while (matcher.find()) {
  326. count++;
  327. }
  328. JSONArray dataJa = new JSONArray();
  329. if (count == 1) {
  330. dataJa.add(text);
  331. } else {
  332. for (int a = 0; a < count; a++) {
  333. int p1 = text.indexOf("end");
  334. dataJa.add(text.substring(0, p1 + 3));
  335. text = text.substring(p1 + 3, text.length());
  336. }
  337. }
  338. return dataJa;
  339. }
  340. }