package com.huimv.env.input.server; import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONArray; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.huimv.env.common.entity.EnvFeed; import com.huimv.env.common.service.IEnvElectricityService; import com.huimv.env.common.service.IEnvFeedService; import com.huimv.env.common.service.IEnvWaterService; import com.huimv.env.input.utils.ModBusUtils; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.io.IOException; import java.math.BigDecimal; import java.text.ParseException; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.huimv.env.input.utils.ModBusUtils.hexStr2Bytes; /** * @Project : huimv.shiwan * @Package : com.huimv.biosafety.uface.controller * @Description : TODO * @Version : 1.0 * @Author : ZhuoNing * @Create : 2020-12-25 **/ @ChannelHandler.Sharable @Component @Slf4j public class EnvInputServerHandler extends ChannelInboundHandlerAdapter { private StringBuilder askTextSb = null; @Autowired private IEnvFeedService envFeedService; // public void appendClientAsk(String text) { if (this.askTextSb == null) { askTextSb = new StringBuilder(); } askTextSb.append(text); } private static long LAST_NOW = System.currentTimeMillis(); @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { Channel channel = ctx.channel(); ByteBuf byteBuf = (ByteBuf) msg; byte[] bytes = new byte[byteBuf.readableBytes()]; byteBuf.readBytes(bytes); String str = ModBusUtils.bytes2HexString(bytes); // System.out.println(str); long now = System.currentTimeMillis(); long time = 5 * 60 * 1000; if ((LAST_NOW + time) < now){ //这里写保存逻辑 try { String cmd = saveWeight(str); System.out.println(cmd); LAST_NOW = now; }catch (Exception e){ System.out.println(e); } } } private String saveWeight(String str) { String[] split = str.split(" "); //FF 11 12 C0 C0 StringBuilder stringBuilder = new StringBuilder(); if (isNumeric(split[4])){ stringBuilder.append(split[4]); } if (isNumeric(split[3])){ stringBuilder.append(split[3]); } if (isNumeric(split[2])) { stringBuilder.append(split[2]); } //当前值 BigDecimal bigDecimal = new BigDecimal(stringBuilder.toString()); EnvFeed id = envFeedService.getOne(new QueryWrapper().orderByDesc("id").last("limit 1")); BigDecimal lastBigDecimal = new BigDecimal(0); if (ObjectUtil.isNotEmpty(id)){ //上一次的值 lastBigDecimal = id.getOriginalValue(); } BigDecimal subtract1 = lastBigDecimal.subtract(bigDecimal); if (subtract1.compareTo(new BigDecimal(1000)) >0 || subtract1.compareTo(new BigDecimal(-1000))<0){ return "差值为" +subtract1 +",舍弃"; } EnvFeed envFeed = new EnvFeed(); envFeed.setFarmId(27); envFeed.setUpdateTime(new Date()); envFeed.setOriginalValue(bigDecimal); if(lastBigDecimal.compareTo(bigDecimal) > 0){ BigDecimal subtract = lastBigDecimal.subtract(bigDecimal).divide(new BigDecimal(1000),3); envFeed.setHandleValue(subtract); }else { envFeed.setHandleValue(new BigDecimal(0)); } envFeedService.save(envFeed); return stringBuilder.toString(); } public static boolean isNumeric(String str) { return str.matches("\\d+"); } /* @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { Channel channel = ctx.channel(); ByteBuf byteBuf = (ByteBuf) msg; byte[] bytes = new byte[byteBuf.readableBytes()]; byteBuf.readBytes(bytes); String str = ModBusUtils.bytes2HexString(bytes); System.out.println("收到的数据:"+str); String cmd = saveWaterAndEle(str); Thread.sleep(5*1000); System.out.println(cmd); channel.writeAndFlush(Unpooled.copiedBuffer(hexStr2Bytes(cmd))); super.channelRead(ctx, msg); } private String saveWaterAndEle(String str) { String[] s = str.split(" "); //读水表 String cmd ="1D 03 00 00 00 02 C6 57"; //读电表 // String cmd ="1C 04 01 00 00 02 73 BA"; if (s.length>10 || s.length<7){ return cmd; } String val = s[3]+s[4]+s[5]+s[6]; System.out.println("val=" +val); Date now = new Date(); //水表 if (str.startsWith("1D 03")){ try { System.out.println("水表"); int waterOrigValue = Integer.parseInt(val, 16); BigDecimal bigDecimal1 = new BigDecimal(waterOrigValue); BigDecimal bigDecimal = new BigDecimal(0); if (!bigDecimal1.equals(0)){ bigDecimal = bigDecimal1.divide(new BigDecimal(100),1,BigDecimal.ROUND_HALF_UP); } EnvWater oldEnvWater = envWaterService.getOne(new QueryWrapper().orderByDesc("id").last("limit 1")); BigDecimal originalValue = oldEnvWater.getOriginalValue(); EnvWater envWater = new EnvWater(); envWater.setOriginalValue(bigDecimal); int i = bigDecimal.compareTo(originalValue); if (ObjectUtil.isNotEmpty(oldEnvWater) && i >= 0) { envWater.setHandleValue(bigDecimal.subtract(originalValue)); }else { envWater.setHandleValue(bigDecimal); } envWater.setUpdateTime(now); envWater.setFarmId(27); envWaterService.save(envWater); cmd = "1C 04 01 00 00 02 73 BA"; }catch (Exception e){ System.out.println(e); } } //电表 if (str.startsWith("1C 04")){ try { System.out.println("电表"); int eleOrigValue = Integer.parseInt(val, 16); Float f = Float.intBitsToFloat(eleOrigValue); BigDecimal bigDecimal = new BigDecimal(f); EnvElectricity oldEnvWater = envElectricityService.getOne(new QueryWrapper().orderByDesc("id").last("limit 1")); BigDecimal originalValue = oldEnvWater.getOriginalValue(); EnvElectricity envElectricity = new EnvElectricity(); envElectricity.setOriginalValue(bigDecimal); int i = bigDecimal.compareTo(originalValue); if (ObjectUtil.isNotEmpty(oldEnvWater) && i>=0){ envElectricity.setHandleValue(bigDecimal.subtract(originalValue)); }else { envElectricity.setHandleValue(bigDecimal.subtract(bigDecimal)); } envElectricity.setUpdateTime(now); envElectricity.setFarmId(27); envElectricityService.save(envElectricity); }catch (Exception e){ System.out.println(e); } } return cmd; } */ private Integer countWeight(String[] s) { int count = 48; return (Integer.parseInt(s[8], 16) -count) +((Integer.parseInt(s[9], 16) -count) * 16) +((Integer.parseInt(s[10], 16) -count) * 256) +((Integer.parseInt(s[11], 16) -count) * 4096) +((Integer.parseInt(s[12], 16) -count) * 6556); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { // if (true){ // ctx.writeAndFlush(Unpooled.copiedBuffer(new byte[]{1, 2, 3})); // } // if (askTextSb.toString().indexOf("end") != -1) { // // {处理客户端消息} // handleClientAskCmd(askTextSb.toString(), ctx); // //清空重置; // askTextSb.delete(0, askTextSb.length()); // } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { if (cause.getMessage().indexOf("Connection reset") != -1) { log.info("相关采集器设备正在重启:" + cause.toString()); } // cause.printStackTrace(); ctx.close(); } /** * @Method : handleClientAskCmd * @Description : 处理请求小心 * @Params : [clientAskText, ctx] * @Return : void * @Author : ZhuoNing * @Date : 2022/3/28 * @Time : 17:36 */ private void handleClientAskCmd(String clientAskText, ChannelHandlerContext ctx) throws ParseException, IOException { clientAskText = clientAskText.replaceAll("\r", "").replaceAll("\n", ""); //{处理非正常命令} // int countPlus = regexUtil.countPlus(clientAskText); // if (countPlus < 4) { // System.out.println("当前数据为不完整数据,故丢弃.>>" + clientAskText); // } else { //--处理客户端请求数据 //{拆分粘包数据} JSONArray askJa = parseAskCmdPackage(clientAskText); for (int a = 0; a < askJa.size(); a++) { String askText = askJa.getString(a); //{处理请求命令} askCmdActuator(askText, ctx); } // } } /** * @Method : askCmdActuator * @Description : * @Params : [askText, ctx] * @Return : void * @Author : ZhuoNing * @Date : 2022/3/23 * @Time : 18:08 */ private void askCmdActuator(String askText, ChannelHandlerContext ctx) throws ParseException, IOException { System.out.println("======>接收设备请求:" + askText); String[] dataArray = askText.split("\\+"); String cmdHeader = dataArray[0]; if (!cmdHeader.trim().equalsIgnoreCase("hm")) { log.info("当前命令是非hm命令[" + askText + "]"); return; } //芯片id/设备编码 String idCode = dataArray[1]; String cmd = dataArray[2]; Map map = new HashMap(); map.put("askText", askText); switch (cmd) { case "1": //获取远程设备编码 getDeviceCode(askText, idCode, ctx); break; case "2": //同步时间 getServerTime(askText, idCode, ctx); break; default: System.out.println("==>未知命令"); log.error(">>当前数据为非法数据-未知命令>>" + askText); } } //时间同步请求 private void getServerTime(String askText, String deviceCode, ChannelHandlerContext ctx) throws ParseException { System.out.println("==>时间同步请求:" + askText); // if (!cmdProService.isEffectiveDevice(deviceCode)) { // System.out.println("##时间同步请求-未注册设备 idCode=" + deviceCode); // return; // } String answerText = "hm+2+" + "+0+4+end"; // log.info(">>时间同步请求-应答数据>>" + answerText); answerCmd(answerText, ctx); } //获取远程设备编码 private void getDeviceCode(String askText, String idCode, ChannelHandlerContext ctx) { System.out.println("==>获取远程设备编码请求:" + askText.trim()); //{读取设备编码} // String deviceCode = cmdProService.getDeviceCodeByChipId(idCode); // log.info("获取远程设备编码请求,芯片id>>" + idCode + " ,deviceCode>>" + deviceCode); // if (deviceCode == null) { // log.error("该设备未注册,已舍弃请求."); // return; // } // String answerText = "hm+1+0+" + deviceCode + "+123+8+end"; // log.info("<<获取远程设备编码请求-应答数据:" + answerText); //{应答指令} // answerCmd(answerText, ctx); } //应答 public void answerCmd(String answerText, ChannelHandlerContext ctx) { ctx.writeAndFlush(Unpooled.copiedBuffer(answerText.getBytes())); } //检查无效耳标 public boolean checkValidEarmark(String earmark) { if (earmark.trim().equalsIgnoreCase("ffffffffffffffff") || earmark.trim().equalsIgnoreCase("0000000000000000")) { return true; } else { return false; } } //拆分粘包数据 public JSONArray parseAskCmdPackage(String text) { String key = "end"; Pattern pattern = Pattern.compile(key); Matcher matcher = pattern.matcher(text); int count = 0; while (matcher.find()) { count++; } JSONArray dataJa = new JSONArray(); if (count == 1) { dataJa.add(text); } else { for (int a = 0; a < count; a++) { int p1 = text.indexOf("end"); dataJa.add(text.substring(0, p1 + 3)); text = text.substring(p1 + 3, text.length()); } } return dataJa; } }