浏览代码

修改device表

pengshaojie 6 年之前
父节点
当前提交
ac1e3470f3

+ 12 - 0
wsm-admin-dao/src/main/java/com/wsm/admin/model/Device.java

@@ -40,6 +40,10 @@ public class Device extends BaseModel implements Serializable {
      */
     @Column(precision = 10, scale = 7)
     private BigDecimal latitude;
+    /**
+     * 地址
+     */
+    private String address;
 
     public String getDeviceId() {
         return deviceId;
@@ -80,4 +84,12 @@ public class Device extends BaseModel implements Serializable {
     public void setDeviceId16Hex(String deviceId16Hex) {
         this.deviceId16Hex = deviceId16Hex;
     }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
 }

+ 4 - 2
wsm-admin-dao/src/main/java/com/wsm/admin/model/DeviceStatus.java

@@ -6,6 +6,9 @@ import org.hibernate.annotations.Where;
 import javax.persistence.*;
 import java.io.Serializable;
 
+/**
+ * 设备状态表
+ */
 @Entity
 @Table(name = "tb_device_status")
 @Where(clause = "rec_status='A'")
@@ -17,9 +20,8 @@ public class DeviceStatus extends BaseModel implements Serializable {
     private Device device;
 
     private String content;
-
     /**
-     * 状态类型:0:当前状态/1:实时报警
+     * 状态类型:0-正常  1-报警  2-低压  3-故障
      */
     @Column(length = 2)
     private Byte status;

+ 29 - 0
wsm-admin-web/src/main/java/com/wsm/admin/api/ApiDeviceController.java

@@ -0,0 +1,29 @@
+package com.wsm.admin.api;
+
+import com.wsm.admin.service.IDeviceService;
+import com.wsm.common.api.BaseController;
+import com.wsm.common.util.AjaxJson;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/api/device")
+public class ApiDeviceController extends BaseController {
+
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Autowired
+    private IDeviceService deviceService;
+
+    /**
+     * 获取所有的设备信息
+     * @return
+     */
+    @RequestMapping(value = {"/list"})
+    public AjaxJson list() {
+       return AjaxJson.success(deviceService.findAll());
+    }
+}

+ 74 - 5
wsm-admin-web/src/main/java/com/wsm/admin/api/DeviceController.java

@@ -1,16 +1,27 @@
 package com.wsm.admin.api;
 
+import com.wsm.admin.model.DataDictionary;
+import com.wsm.admin.model.Device;
+import com.wsm.admin.service.IDataDictionaryService;
 import com.wsm.admin.service.IDeviceService;
 import com.wsm.common.api.BaseController;
 import com.wsm.common.util.AjaxJson;
+import com.wsm.common.util.ConstantUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
 
-@RestController
-@RequestMapping("/api/device")
+@Controller
+@RequestMapping("/admin/device")
 public class DeviceController extends BaseController {
 
     private Logger logger = LoggerFactory.getLogger(getClass());
@@ -19,7 +30,65 @@ public class DeviceController extends BaseController {
     private IDeviceService deviceService;
 
     @RequestMapping(value = {"/list"})
-    public AjaxJson list() {
-       return AjaxJson.success(deviceService.findAll());
+    public String index(Model model) {
+        Page<Device> deviceList = deviceService.findAll(getPageRequest(
+                new Sort(Sort.Direction.DESC, "id")));
+        model.addAttribute("deviceList", deviceList);
+        return "/admin/device/list";
     }
+
+    @RequestMapping(value = {"/detail"}, method = RequestMethod.GET)
+    public String detail(@RequestParam(required = false) String deviceId, Model model) {
+        Device device = new Device();
+        if (deviceId != null) {
+            device = deviceService.find(Long.valueOf(deviceId));
+        }
+        model.addAttribute("device", device);
+        return "/admin/device/form";
+    }
+
+    @RequestMapping(value = {"/save"}, method = RequestMethod.POST)
+    @ResponseBody
+    public AjaxJson edit(Device device) {
+        try {
+            if (device.getId() != null) {
+                Device dbDevice = deviceService.find(Long.valueOf(device.getId()));
+                dbDevice.setDeviceId16Hex(device.getDeviceId16Hex());
+                dbDevice.setDeviceId(device.getDeviceId());
+                dbDevice.setDeviceType(device.getDeviceType());
+                deviceService.update(device);
+            }else{
+                deviceService.save(device);
+            }
+        } catch (Exception e) {
+            logger.error("系统异常:", e);
+            return AjaxJson.failure("系统异常:"+e);
+        }
+        return AjaxJson.success();
+    }
+
+    /**
+     * 删除
+     */
+    @RequestMapping(value = {"/remove"}, method = RequestMethod.POST)
+    @ResponseBody
+    public AjaxJson remove(String deviceId) {
+        AjaxJson ajaxJson = null;
+        try {
+            if (!StringUtils.isEmpty(deviceId)) {
+                Device dbDevice = deviceService.find(Long.valueOf(deviceId));
+                dbDevice.setRecStatus("I");
+                deviceService.update(dbDevice);
+                ajaxJson =  AjaxJson.success(ConstantUtils.SUCCESS_MSG);
+            }else{
+                ajaxJson = AjaxJson.failure("id不能为空");
+            }
+        } catch (Exception e) {
+            logger.error("系统异常:", e);
+            return AjaxJson.failure("系统异常:" + e);
+        }
+        return ajaxJson;
+    }
+
 }
+

+ 24 - 107
wsm-admin-web/src/main/java/com/wsm/admin/handle/UdpServerHandler.java

@@ -7,13 +7,14 @@ import com.wsm.admin.service.IDeviceService;
 import com.wsm.admin.service.IDeviceStatusService;
 import com.wsm.admin.service.impl.DeviceServiceImpl;
 import com.wsm.admin.service.impl.DeviceStatusServiceImpl;
-import com.wsm.common.util.ASCIIUtil;
+import com.wsm.common.util.DeviceUtil;
+import com.wsm.common.util.ByteUtil;
 import com.wsm.common.util.SpringContext;
+import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.SimpleChannelInboundHandler;
 import io.netty.channel.socket.DatagramPacket;
-import io.netty.util.CharsetUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.joda.time.DateTime;
 import org.joda.time.format.DateTimeFormat;
@@ -52,35 +53,9 @@ public class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket
         }
     }
 
-    private static final Map<String, String> deviceStatusMap = new HashMap<>();
     private static final Map<String, String> jgDeviceStatusMap = new HashMap<>();
 
     static {
-        deviceStatusMap.put("08", "硬件版本号");
-        deviceStatusMap.put("15", "SIM 卡CCID 号码");
-        deviceStatusMap.put("05", "NB/GPRS 信号强度");
-        deviceStatusMap.put("2A00", "电池:低压");
-        deviceStatusMap.put("3500", "NB底座的电池:低压");
-        deviceStatusMap.put("3600", "烟感底座上的烟感电池:低压");
-        deviceStatusMap.put("3701", "消防门状态:打开");
-        deviceStatusMap.put("3801", "消防手报状态:弹起");
-        deviceStatusMap.put("3E01", "喷淋状态:打开");
-
-        deviceStatusMap.put("111", "烟雾报警");
-        deviceStatusMap.put("384", "低压报警");
-        deviceStatusMap.put("993", "底座上的烟感低压");
-        deviceStatusMap.put("992", "NB 底座低压报警 ");
-        deviceStatusMap.put("991", "燃气报警");
-        deviceStatusMap.put("990", "消防手报按钮报警");
-        deviceStatusMap.put("989", "消防门打开");
-        deviceStatusMap.put("988", "消防门关闭");
-        deviceStatusMap.put("987", "消防门长时间未关闭");
-        deviceStatusMap.put("986", "高温报警");
-        deviceStatusMap.put("985", "漏电报警");
-        deviceStatusMap.put("984", "温感低压");
-        deviceStatusMap.put("966", "喷淋打开");
-        deviceStatusMap.put("965", "喷淋关闭");
-
         jgDeviceStatusMap.put("ERC52", "水浸事件");
         jgDeviceStatusMap.put("ERC51", "井盖掀翻");
         jgDeviceStatusMap.put("ERC50", "井盖倾斜/抬起");
@@ -88,21 +63,20 @@ public class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket
 
     @Override
     public void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
-        String receiveMsg = packet.content().toString(CharsetUtil.UTF_8);
-        log.warn("Received UDP Msg:" + receiveMsg);
+        ByteBuf buf = packet.copy().content();
+        //通过ByteBuf的readableBytes方法可以获取缓冲区可读的字节数,
+        //根据可读的字节数创建byte数组
+        byte[] req = new byte[buf.readableBytes()];
+        buf.readBytes(req);
+        String receiveMsg = ByteUtil.bytesToHexString(req).toUpperCase();
+        log.warn("Received UDP Msg :" + receiveMsg);
 
         if (StringUtils.isNotEmpty(receiveMsg)){
-            String feedback = "";
-            // 井盖
-            if (receiveMsg.startsWith("2B")){
-                feedback = handleYG(receiveMsg);
-                //byte[] data = feedback.getBytes("ASCII");
-            }else if (receiveMsg.startsWith("68")){
-                feedback = handleJG(receiveMsg);
-            }
+            String feedback = handleJG(receiveMsg);
+            // 由于数据报的数据是以字符数组传的形式存储的,所以传转数据
+            byte[] bytes = feedback.getBytes("UTF-8");
             //在这里可以返回一个UDP消息给对方
-            ctx.write(new DatagramPacket(
-                    Unpooled.copiedBuffer(feedback , CharsetUtil.UTF_8), packet.sender()));
+            ctx.write(new DatagramPacket(Unpooled.copiedBuffer(bytes), packet.sender()));
         }else{
             log.error("Received Error UDP Message:" + receiveMsg);
         }
@@ -113,7 +87,7 @@ public class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket
         StringBuffer lStr = new StringBuffer("4B");
 
         log.warn("======接收到井盖传感器推送信息======");
-        String[] str = ASCIIUtil.turnToArray(receiveMsg);
+        String[] str = DeviceUtil.turnToArray(receiveMsg);
         String afn  = str[12];
         String fn = str[14]+str[15]+str[16]+str[17];
         String frameNumber = str[13];
@@ -122,18 +96,18 @@ public class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket
 //        log.warn("倒数第一个字符:"+str[str.length-1]);
 //        log.warn("倒数第二个字符:"+str[str.length-2]);
 
-        String deviceId = ASCIIUtil.getJGDeviceID(str);
+        String deviceId = DeviceUtil.getJGDeviceID(str);
         log.warn("设备号:"+deviceId);
 
-        lStr.append(ASCIIUtil.getFeedBackJGDeviceID(str)).append("04").append(afn).append(frameNumber).append(fn);
+        lStr.append(DeviceUtil.getFeedBackJGDeviceID(str)).append("04").append(afn).append(frameNumber).append(fn);
         String body = receiveMsg.substring(36, receiveMsg.length()-4);
-        String[] bodyStr = ASCIIUtil.turnToArray(body);
+        String[] bodyStr = DeviceUtil.turnToArray(body);
         log.warn("数据体是:" + body);
 
         if (StringUtils.isNotEmpty(body)){
             StringBuffer feedbackBody = new StringBuffer();
             feedbackBody.append("00").append("00").append("EE").append("32131031C318").append("00000000000000000000000000000000000000")
-                    .append("EE").append("C0").append("A8").append("01").append("E1").append("2008").append("EE").append(ASCIIUtil.getFeedBackJGDeviceID(str))
+                    .append("EE").append("C0").append("A8").append("01").append("E1").append("2008").append("EE").append(DeviceUtil.getFeedBackJGDeviceID(str))
                     .append("55").append("00000000").append("EE").append("1008").append("00000000000000000000");
             lStr.append(feedbackBody);
 
@@ -145,7 +119,7 @@ public class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket
                 log.warn("=======第"+(i+1)+"个事件=======");
                 String eventStr = body.substring(8 + i*length, (8 + i*length)+26);
                 log.warn("======="+eventStr +"=======");
-                String[] eventStrArr = ASCIIUtil.turnToArray(eventStr);
+                String[] eventStrArr = DeviceUtil.turnToArray(eventStr);
                 String type = "ERC" + parseLong(eventStrArr[0], 16);
                 if (jgDeviceStatusMap.get(type) != null){
                     log.warn("======="+jgDeviceStatusMap.get(type)+"=======\n");
@@ -177,79 +151,22 @@ public class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket
         }else{
             log.warn("推送的是上报完毕报文");
         }
-        StringBuffer a = new StringBuffer(ASCIIUtil.toBinary(lStr.toString().length()/2)).append("10");
+        StringBuffer a = new StringBuffer(ByteUtil.toBinary(lStr.toString().length()/2)).append("10");
         StringBuffer zero = new StringBuffer();
         for (int i = 0; i < 16-a.length(); i++){
             zero.append("0");
         }
         zero.append(a);
-        String ab = ASCIIUtil.binaryString2hexString(zero.toString());
-        String[] abArr = ASCIIUtil.turnToArray(ab);
+        String ab = ByteUtil.binaryString2hexString(zero.toString());
+        String[] abArr = DeviceUtil.turnToArray(ab);
         feedback.append(abArr[1]).append(abArr[0]).append(abArr[1]).append(abArr[0]).append("68");
-        lStr.append(ASCIIUtil.makeChecksum(lStr.toString()));
+        lStr.append(ByteUtil.makeChecksum(lStr.toString()));
         lStr.append("16");
         feedback.append(lStr);
         return feedback.toString().toUpperCase();
     }
 
-    private String handleYG(String receiveMsg) {
-        log.warn("======接收到烟感传感器推送信息======");
-        String[] str = ASCIIUtil.turnToArray(receiveMsg);
-        Device device = deviceService.findByDeviceId16Hex(ASCIIUtil.getYGDeviceID(str));
-
-        String type = str[6];
-        switch (type){
-            // 心跳
-            case "02":
-                break;
-            // 状态
-            case "04":
-                int total = Integer.valueOf(str[16]);
-                for (int i = 0, length = 3; i < total; i++){
-                    String a = str[17 + i * length];
-                    //String b = str[18 + i * length];
-                    String c = str[19 + i * length];
-                    // 状态异常
-                    if (!org.springframework.util.StringUtils.isEmpty(deviceStatusMap.get(a+c)) && device != null){
-                        DeviceStatus status =  new DeviceStatus();
-                        status.setContent(deviceStatusMap.get(a+c));
-                        status.setDevice(device);
-                        status.setStatus((byte)0);
-                        deviceStatusService.save(status);
-                        log.warn(device.getDeviceId() + ":"+ status.getContent());
-
-                        JSONObject result = new JSONObject();
-                        result.put("id", device.getDeviceId());
-                        result.put("deviceType", device.getDeviceType());
-                        result.put("status", a+c);
-
-                        messagingTemplate.convertAndSend("/topic/device", result.toJSONString());
-                    }
-                }
-                break;
-            // 报警
-            case "09":
-                // 报警
-                String hex = ASCIIUtil.hexStringToString(str[24]+str[25]+str[26]);
-                if (!org.springframework.util.StringUtils.isEmpty(deviceStatusMap.get(hex)) && device != null){
-                    DeviceStatus status =  new DeviceStatus();
-                    status.setContent(deviceStatusMap.get(hex));
-                    status.setDevice(device);
-                    status.setStatus((byte)1);
-                    deviceStatusService.save(status);
-                    log.warn(device.getDeviceId() + ":"+ status.getContent());
-
-                    JSONObject result = new JSONObject();
-                    result.put("id", device.getDeviceId());
-                    result.put("deviceType", device.getDeviceType());
-                    result.put("status", hex);
-                    messagingTemplate.convertAndSend("/topic/device", result.toJSONString());
-                }
-                break;
-        }
 
-        return ASCIIUtil.getOKFeedback(str);
-    }
 
     @Override
     public void channelReadComplete(ChannelHandlerContext ctx) {

+ 5 - 1
wsm-admin-web/src/main/java/com/wsm/admin/init/StartupUdpEvent.java

@@ -17,11 +17,15 @@ public class StartupUdpEvent implements ApplicationListener<ContextRefreshedEven
         try {
             context = contextRefreshedEvent.getApplicationContext();
 
-            log.warn("启动UDP线程,接收UDP消息");
+            log.warn("启动UDP线程,接收UDP消息,端口:2000");
             //接收UDP消息并保存至redis中
             UdpServer udpServer = (UdpServer)StartupUdpEvent.getBean(UdpServer.class);
             udpServer.run(2000);
 
+            log.warn("启动TCP线程,接收TCP消息,端口:2020");
+            TcpServer tcpServer = (TcpServer)StartupUdpEvent.getBean(TcpServer.class);
+            tcpServer.startSocketServer(2020);
+
         } catch (Exception e) {
             log.error("Exception", e);
         }

+ 228 - 0
wsm-admin-web/src/main/java/com/wsm/admin/init/TcpServer.java

@@ -0,0 +1,228 @@
+package com.wsm.admin.init;
+
+import com.alibaba.fastjson.JSONObject;
+import com.wsm.admin.model.Device;
+import com.wsm.admin.model.DeviceStatus;
+import com.wsm.admin.service.IDeviceService;
+import com.wsm.admin.service.IDeviceStatusService;
+import com.wsm.common.util.ByteUtil;
+import com.wsm.common.util.DeviceUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+@Component
+public class TcpServer {
+    private static final Logger log = LoggerFactory.getLogger(TcpServer.class);
+
+    //解码buffer
+    private Charset cs = Charset.forName("UTF-8");
+    //发送数据缓冲区
+    private static ByteBuffer sBuffer = ByteBuffer.allocate(1024);
+    //接受数据缓冲区
+    private static ByteBuffer rBuffer = ByteBuffer.allocate(1024);
+    //选择器(叫监听器更准确些吧应该)
+    private static Selector selector;
+
+    @Autowired
+    private IDeviceStatusService deviceStatusService;
+    @Autowired
+    private IDeviceService deviceService;
+    @Autowired
+    private SimpMessagingTemplate messagingTemplate;
+
+    private static final Map<String, String> deviceStatusMap = new HashMap<>();
+
+    static {
+        deviceStatusMap.put("08", "硬件版本号");
+        deviceStatusMap.put("15", "SIM 卡CCID 号码");
+        deviceStatusMap.put("05", "NB/GPRS 信号强度");
+        deviceStatusMap.put("2A00", "电池:低压");
+        deviceStatusMap.put("3500", "NB底座的电池:低压");
+        deviceStatusMap.put("3600", "烟感底座上的烟感电池:低压");
+        deviceStatusMap.put("3701", "消防门状态:打开");
+        deviceStatusMap.put("3801", "消防手报状态:弹起");
+        deviceStatusMap.put("3E01", "喷淋状态:打开");
+
+        deviceStatusMap.put("111", "烟雾报警");
+        deviceStatusMap.put("384", "低压报警");
+        deviceStatusMap.put("993", "底座上的烟感低压");
+        deviceStatusMap.put("992", "NB 底座低压报警 ");
+        deviceStatusMap.put("991", "燃气报警");
+        deviceStatusMap.put("990", "消防手报按钮报警");
+        deviceStatusMap.put("989", "消防门打开");
+        deviceStatusMap.put("988", "消防门关闭");
+        deviceStatusMap.put("987", "消防门长时间未关闭");
+        deviceStatusMap.put("986", "高温报警");
+        deviceStatusMap.put("985", "漏电报警");
+        deviceStatusMap.put("984", "温感低压");
+        deviceStatusMap.put("966", "喷淋打开");
+        deviceStatusMap.put("965", "喷淋关闭");
+
+    }
+
+    /**
+     * 启动socket服务,开启监听
+     *
+     * @param port
+     * @throws IOException
+     */
+    @Async("updAsyncPool")
+    public void startSocketServer(int port) {
+        try {
+            //打开通信信道
+            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
+            //设置为非阻塞
+            serverSocketChannel.configureBlocking(false);
+            //获取套接字
+            ServerSocket serverSocket = serverSocketChannel.socket();
+            //绑定端口号
+            serverSocket.bind(new InetSocketAddress(port));
+            //打开监听器
+            selector = Selector.open();
+            //将通信信道注册到监听器
+            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
+
+            //监听器会一直监听,如果客户端有请求就会进入相应的事件处理
+            while (true) {
+                selector.select();//select方法会一直阻塞直到有相关事件发生或超时
+                Set<SelectionKey> selectionKeys = selector.selectedKeys();//监听到的事件
+                for (SelectionKey key : selectionKeys) {
+                    handle(key);
+                }
+                selectionKeys.clear();//清除处理过的事件
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 处理不同的事件
+     *
+     * @param selectionKey
+     * @throws IOException
+     */
+    private void handle(SelectionKey selectionKey) throws IOException {
+        ServerSocketChannel serverSocketChannel = null;
+        SocketChannel socketChannel = null;
+        String requestMsg = "";
+        String responseMsg = "";
+        int count = 0;
+        if (selectionKey.isAcceptable()) {
+            //每有客户端连接,即注册通信信道为可读
+            serverSocketChannel = (ServerSocketChannel) selectionKey.channel();
+            socketChannel = serverSocketChannel.accept();
+            socketChannel.configureBlocking(false);
+            socketChannel.register(selector, SelectionKey.OP_READ);
+        } else if (selectionKey.isReadable()) {
+            socketChannel = (SocketChannel) selectionKey.channel();
+            rBuffer.clear();
+            count = socketChannel.read(rBuffer);
+            //读取数据
+            if (count > 0) {
+                rBuffer.flip();
+
+                byte[] bytes = new byte[rBuffer.remaining()];
+                rBuffer.get(bytes, 0, bytes.length);
+
+                requestMsg = ByteUtil.bytesToHexString(bytes).toUpperCase();
+                log.warn("Received TCP Msg :" + requestMsg);
+
+                try {
+                    responseMsg = handleYG(requestMsg);
+                }catch (Exception ex){
+                    log.error(ex.getMessage());
+                }
+            }
+            //返回数据
+            sBuffer = ByteBuffer.allocate(responseMsg.getBytes("UTF-8").length);
+            sBuffer.put(responseMsg.getBytes("UTF-8"));
+            sBuffer.flip();
+            socketChannel.write(sBuffer);
+            socketChannel.close();
+        }
+    }
+
+    private String handleYG(String receiveMsg) {
+        log.warn("======接收到烟感传感器推送信息======");
+        String[] str = DeviceUtil.turnToArray(receiveMsg);
+        String deviceID = DeviceUtil.getYGDeviceID(str);
+        log.warn("deviceID:"+deviceID);
+        Device device = deviceService.findByDeviceId16Hex(deviceID);
+        if (device != null){
+            log.warn("接收到:"+device.getDeviceId()+" 推送的信息");
+        }
+
+        String type = str[6];
+        switch (type){
+            // 心跳
+            case "02":
+                log.warn("======心跳信息,无异常状态======");
+                break;
+            // 状态
+            case "04":
+                int total = Integer.valueOf(str[16]);
+                for (int i = 0, length = 3; i < total; i++){
+                    String a = str[17 + i * length];
+                    //String b = str[18 + i * length];
+                    String c = str[19 + i * length];
+                    // 状态异常
+                    if (!org.springframework.util.StringUtils.isEmpty(deviceStatusMap.get(a+c)) && device != null){
+                        DeviceStatus status =  new DeviceStatus();
+                        status.setContent(deviceStatusMap.get(a+c));
+                        status.setDevice(device);
+                        status.setStatus((byte)0);
+                        deviceStatusService.save(status);
+                        log.warn(device.getDeviceId() + ":"+ status.getContent());
+
+                        JSONObject result = new JSONObject();
+                        result.put("id", device.getDeviceId());
+                        result.put("deviceType", device.getDeviceType());
+                        result.put("status", a+c);
+
+                        messagingTemplate.convertAndSend("/topic/device", result.toJSONString());
+                    }
+                }
+                break;
+            // 报警
+            case "09":
+                // 报警
+                String hex = ByteUtil.hexStringToString(str[24]+str[25]+str[26]);
+                if (!org.springframework.util.StringUtils.isEmpty(deviceStatusMap.get(hex)) && device != null){
+                    DeviceStatus status =  new DeviceStatus();
+                    status.setContent(deviceStatusMap.get(hex));
+                    status.setDevice(device);
+                    status.setStatus((byte)1);
+                    deviceStatusService.save(status);
+                    log.warn(device.getDeviceId() + ":"+ status.getContent());
+
+                    JSONObject result = new JSONObject();
+                    result.put("id", device.getDeviceId());
+                    result.put("deviceType", device.getDeviceType());
+                    result.put("status", hex);
+                    messagingTemplate.convertAndSend("/topic/device", result.toJSONString());
+                }
+                break;
+        }
+
+        return DeviceUtil.getOKFeedback(str);
+    }
+
+}

+ 0 - 23
wsm-admin-web/src/main/java/com/wsm/admin/shiro/ShiroConfig.java

@@ -106,34 +106,11 @@ public class ShiroConfig {
         filterChainDefinitionMap.put("/live/**", "anon");
         filterChainDefinitionMap.put("/static/**", "anon");
         filterChainDefinitionMap.put("/index.html", "anon");
-        filterChainDefinitionMap.put("/mobile.html", "anon");
         filterChainDefinitionMap.put("/css/**", "anon");
         filterChainDefinitionMap.put("/img/**", "anon");
         filterChainDefinitionMap.put("/js/**", "anon");
-        filterChainDefinitionMap.put("/language/**", "anon");
         filterChainDefinitionMap.put("/plugins/**", "anon");
-        filterChainDefinitionMap.put("/member_head_image/**", "anon");
         filterChainDefinitionMap.put("/audio/**", "anon");
-        filterChainDefinitionMap.put("/*.js", "anon");
-        filterChainDefinitionMap.put("/*.png", "anon");
-        filterChainDefinitionMap.put("/*.jpg", "anon");
-        filterChainDefinitionMap.put("/*.jpeg", "anon");
-        filterChainDefinitionMap.put("/*.JPG", "anon");
-        filterChainDefinitionMap.put("/*.JPEG", "anon");
-        filterChainDefinitionMap.put("/*.PNG", "anon");
-        filterChainDefinitionMap.put("/*.mp3", "anon");
-        filterChainDefinitionMap.put("/*.wav", "anon");
-        filterChainDefinitionMap.put("/*.wma", "anon");
-        filterChainDefinitionMap.put("/*.asf", "anon");
-        filterChainDefinitionMap.put("/*.aac", "anon");
-        filterChainDefinitionMap.put("/*.vqf", "anon");
-        filterChainDefinitionMap.put("/*.flac", "anon");
-        filterChainDefinitionMap.put("/*.ape", "anon");
-        filterChainDefinitionMap.put("/*.mid", "anon");
-        filterChainDefinitionMap.put("/*.ogg", "anon");
-        filterChainDefinitionMap.put("/*.m4a", "anon");
-        filterChainDefinitionMap.put("/*.mod", "anon");
-
         //登录链接不拦截
         filterChainDefinitionMap.put("/admin/login", "anon");
         filterChainDefinitionMap.put("/admin", "anon");

+ 9 - 9
wsm-application/src/main/resources/application.properties

@@ -31,24 +31,24 @@ spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/reso
 spring.redis.database=0
 spring.redis.host=127.0.0.1
 spring.redis.port=6379
-# ���ӳ�ʱʱ�� ��λ ms�����룩
+# 连接超时时间 单位 ms(毫秒)
 spring.redis.timeout=3000
-# ���ӳ��е����������ӣ�Ĭ��ֵҲ��8��
+# 连接池中的最大空闲连接,默认值也是8。
 spring.redis.pool.max-idle=8
-#���ӳ��е���С�������ӣ�Ĭ��ֵҲ��0��
+#连接池中的最小空闲连接,默认值也是0。
 spring.redis.pool.min-idle=0
-# �����ֵΪ-1�����ʾ�����ƣ����pool�Ѿ�������maxActive��jedisʵ�������ʱpool��״̬Ϊexhausted(�ľ�)��
+# 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
 spring.redis.pool.max-active=8
-# �ȴ��������ӵ����ʱ�䣬��λ���룬Ĭ��ֵΪ-1����ʾ������ʱ����������ȴ�ʱ�䣬��ֱ���׳�JedisConnectionException
+# 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
 spring.redis.pool.max-wait=-1
-#redis�ڱ�����
-#Redis������master������
+#redis哨兵设置
+#Redis服务器master的名字
 #spring.redis.sentinel.master=master8026
-#redis-sentinel�����õ�ַ�Ͷ˿�
+#redis-sentinel的配置地址和端口
 #spring.redis.sentinel.nodes=10.189.80.25:26379,10.189.80.26:26379,10.189.80.27:26378
 
 context.listener.classes=com.wsm.admin.init.StartupUdpEvent
-#�̳߳�
+#线程池
 spring.task.pool.corePoolSize=5
 spring.task.pool.maxPoolSize=100
 spring.task.pool.keepAliveSeconds=100

+ 98 - 0
wsm-application/src/main/resources/templates/admin/device/form.html

@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"
+>
+<head>
+    <meta charset="UTF-8">
+    <title>设备编辑</title>
+    <link rel="stylesheet" href="/css/metroStyle/metroStyle.css">
+    <link rel="stylesheet" href="/plugins/layui/css/layui.css">
+    <link rel="stylesheet" href="/css/public.css">
+    <style type="text/css">
+        .layui-form-label {
+            width: 100px;
+        }
+    </style>
+</head>
+<body class="child-body">
+<div class="child-nav">
+    <span class="layui-breadcrumb">
+         <a>系统管理</a>
+         <a href="/admin/device/list">设备列表</a>
+         <a><cite th:text="${#strings.equals(device.id,null)?'新增设备':'修改设备'}"></cite></a>
+    </span>
+    <a class="layui-btn layui-btn-sm" href="javascript:location.replace(location.href);" title="刷新"
+       style="float:right;margin-top: 3px"><i class="layui-icon" style="line-height:30px">&#x1002;</i></a>
+</div>
+<div class="layui-col-md12">
+    <div class="layui-card">
+        <div class="layui-card-header" th:text="${#strings.equals(device.id,null)?'新增设备':'修改设备'}"></div>
+        <div class="layui-card-body">
+            <form class="layui-form" action="/admin/device/save" method="post">
+                <input type="hidden" id="deviceId" name="id" th:value="${device.id}">
+                <div class="layui-form-item">
+                    <label class="layui-form-label">设备号</label>
+                    <div class="layui-input-inline">
+                        <input type="text" name="deviceId" th:value="${device.deviceId}" lay-verify="required"
+                               lay-vertype="tips" class="layui-input" >
+                    </div>
+                </div>
+                <div class="layui-form-item">
+                    <label class="layui-form-label">设备号16进制码</label>
+                    <div class="layui-input-inline">
+                        <input type="text" name="deviceId16Hex" th:value="${device.deviceId16Hex}" lay-verify="required"
+                               lay-vertype="tips" class="layui-input" >
+                    </div>
+                </div>
+                <div class="layui-form-item">
+                    <label class="layui-form-label">设备类型</label>
+                    <div class="layui-input-inline">
+                        <select name="deviceType" lay-verify="required">
+                            <option value="YG" th:selected="${#strings.equals(device.deviceType,'YG')}">烟感</option>
+                            <option value="JG" th:selected="${#strings.equals(device.deviceType,'JG')}">井盖</option>
+                        </select>
+                    </div>
+                </div>
+                <div class="layui-form-item">
+                    <div class="layui-input-block">
+                        <button class="layui-btn" lay-submit lay-filter="save"
+                                th:text="${#strings.equals(device.id,null)?'保存':'修改'}"></button>
+                        <a href="javascript:history.back()" type="button" class="layui-btn layui-btn-primary">返回</a>
+                    </div>
+                </div>
+            </form>
+        </div>
+    </div>
+</div>
+<script src="/plugins/layui/layui.js"></script>
+<script type="text/javascript">
+    layui.use(['element', 'form', 'laydate', 'upload'], function () {
+        var form = layui.form, $ = layui.jquery;
+
+        //监听提交
+        form.on('submit(save)', function (data) {
+            var headers = {};
+            headers['X-CSRF-TOKEN'] = "[[${_csrf.token}]]";
+            $.ajax({
+                url: data.form.action,
+                type: data.form.method,
+                headers: headers,
+                data: data.field,
+                dataType: 'json',
+                success: function (data) {
+                    if (data.code == 0) {
+                        layer.msg(data.msg, {icon: 1, time: 1000}, function () {
+                            location.href = "/admin/device/list";
+                        });
+                    } else {
+                        layer.msg(data.msg, {time: 1000});
+                    }
+                }
+            });
+            return false;
+        });
+
+        form.render();
+    });
+</script>
+</body>
+</html>

+ 123 - 0
wsm-application/src/main/resources/templates/admin/device/list.html

@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
+<head>
+    <meta charset="UTF-8"/>
+    <meta name="renderer" content="webkit"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
+    <meta name="apple-mobile-web-app-status-bar-style" content="black"/>
+    <meta name="apple-mobile-web-app-capable" content="yes"/>
+    <title>设备列表</title>
+    <link rel="stylesheet" href="/plugins/layui/css/layui.css"/>
+    <link rel="stylesheet" href="/css/public.css"/>
+</head>
+<body class="child-body">
+
+<div class="child-nav">
+    <span class="layui-breadcrumb">
+         <a>系统管理</a>
+         <a><cite>设备列表</cite></a>
+    </span>
+    <a class="layui-btn layui-btn-sm" href="javascript:location.replace(location.href);" title="刷新"
+       style="float:right;margin-top: 3px">
+        <i class="layui-icon" style="line-height:30px">&#x1002;</i>
+    </a>
+</div>
+
+<div class="layui-row">
+    <form class="layui-form">
+        <div class="layui-form-item">
+            <div class="layui-inline">
+                <a href="/admin/device/detail" type="button"
+                   class="layui-btn layui-btn-sm"><i class="layui-icon">&#xe608;</i>新增</a>
+            </div>
+        </div>
+    </form>
+</div>
+
+<table class="layui-table" id="devicePage" lay-filter="devicePage">
+    <thead>
+    <tr>
+        <th lay-data="{field:'id', sort: true}">Id</th>
+        <th lay-data="{field:'deviceId', sort: true}">设备id</th>
+        <th lay-data="{field:'deviceType', sort: true}">设备类型</th>
+        <th lay-data="{field:'opt', fixed: 'right', align:'center', width:300}">操作</th>
+    </tr>
+    </thead>
+    <tbody>
+    <tr th:each="device:${deviceList}">
+        <td th:text="${device.id}"></td>
+        <td th:text="${device.deviceId}"></td>
+        <td th:if="${device.deviceType=='YG'}">烟感</td>
+        <td th:if="${device.deviceType=='JG'}">井盖</td>
+        <td>
+            <a class="layui-btn layui-btn-xs" lay-event="detail">
+                <i class="layui-icon">&#xe642;</i>编辑</a>
+            <a class="layui-btn layui-btn-xs layui-btn-danger"
+               lay-event="delete"><i class="layui-icon">&#xe640;</i>删除</a>
+        </td>
+    </tr>
+    </tbody>
+</table>
+<div id="pag"></div>
+<script src="/plugins/layui/layui.js"></script>
+<script th:inline="javascript">
+    /*<![CDATA[*/
+    var pageable = [[${deviceList}]];
+    /*]]>*/
+
+    layui.use(['element', 'laypage', 'layer', 'table', 'laydate'], function () {
+        var $ = layui.jquery;
+        var table = layui.table, laypage = layui.laypage;
+
+        table.init('devicePage', {limit: pageable.size});
+
+        laypage.render({
+            elem: 'pag',
+            count: pageable.totalElements,
+            groups: 10,
+            limit: pageable.size,
+            curr: pageable.number + 1,
+            layout: ['prev', 'page', 'next', 'skip', 'count', 'limit'],
+            jump: function (obj, first) {
+                if (!first) {
+                    window.location.href = "/admin/device/list?page=" + obj.curr + "&limit=" + obj.limit;
+                }
+            }
+        });
+
+        table.on('tool(devicePage)', function (obj) {
+            if (obj.event === 'detail') {
+                location.href = "/admin/device/detail?deviceId=" + obj.data.id;
+            } else if (obj.event === 'delete') {
+                layer.msg('确定要删除该数据吗?', {
+                    time: 0,
+                    shade: [0.5, '#fff'],
+                    btn: ['确定', '取消'],
+                    yes: function (index) {
+                        $.ajax({
+                            url: '/admin/device/remove',
+                            type: 'POST',
+                            data: {deviceId: obj.data.id},
+                            dataType: 'json',
+                            success: function (data) {
+                                if (data.code == 0) {
+                                    layer.msg(data.msg, {icon: 1, time: 1000}, function () {
+                                        location.reload();
+                                    });
+                                } else {
+                                    layer.msg(data.msg, {time: 1000});
+                                }
+                            }
+                        });
+                    }
+                });
+            }
+        });
+
+
+    });
+
+</script>
+</body>
+</html>

+ 136 - 136
wsm-common/src/main/java/com/wsm/common/util/ASCIIUtil.java

@@ -1,75 +1,60 @@
 package com.wsm.common.util;
 
-public class ASCIIUtil {
+public class ByteUtil {
 
-    private static String hexStr =  "0123456789ABCDEF";
+    private static String hexStr = "0123456789ABCDEF";
     private static String[] binaryArray =
-            {"0000","0001","0010","0011",
-                    "0100","0101","0110","0111",
-                    "1000","1001","1010","1011",
-                    "1100","1101","1110","1111"};
+            {"0000", "0001", "0010", "0011",
+                    "0100", "0101", "0110", "0111",
+                    "1000", "1001", "1010", "1011",
+                    "1100", "1101", "1110", "1111"};
 
-    // 累加
-    public static String makeChecksum(String data) {
-        if (data == null || data.equals("")) {
-            return "";
-        }
-        int total = 0;
-        int len = data.length();
-        int num = 0;
-        while (num < len) {
-            String s = data.substring(num, num + 2);
-            total += Integer.parseInt(s, 16);
-            num = num + 2;
+    /**
+     * 将二进制转换为十六进制字符输出
+     *
+     * @param src
+     * @return
+     */
+    public static String bytesToHexString(byte[] src) {
+        StringBuilder stringBuilder = new StringBuilder("");
+        if (src == null || src.length <= 0) {
+            return null;
         }
-        /**
-         * 用256求余最大是255,即16进制的FF
-         */
-        int mod = total % 256;
-        String hex = Integer.toHexString(mod);
-        len = hex.length();
-        // 如果不够校验位的长度,补0,这里用的是两位校验
-        if (len < 2) {
-            hex = "0" + hex;
+        for (int i = 0; i < src.length; i++) {
+            int v = src[i] & 0xFF;
+            String hv = Integer.toHexString(v);
+            if (hv.length() < 2) {
+                stringBuilder.append(0);
+            }
+            stringBuilder.append(hv);
         }
-        return hex;
-    }
-
-    public static String[] turnToArray(String replace) {
-        String regex = "(.{2})";
-        replace = replace.replaceAll(regex, "$1,");
-        return replace.split(",");
-    }
-
-    public static String numToHex8(int b) {
-        return String.format("%02x", b);//2表示需要两个16进行数
-    }
-    //需要使用2字节表示b
-    public static String numToHex16(int b) {
-        return String.format("%04x", b);
-    }
-    //需要使用4字节表示b
-    public static String numToHex32(int b) {
-        return String.format("%08x", b);
+        return stringBuilder.toString();
     }
 
     /**
-     * 字符串转化成为16进制字符串
-     * @param s
+     * 转换为二进制字符串
+     *
+     * @param bArray
      * @return
      */
-    public static String strTo16(String s) {
-        String str = "";
-        for (int i = 0; i < s.length(); i++) {
-            int ch = (int) s.charAt(i);
-            String s4 = Integer.toHexString(ch);
-            str = str + s4;
+    public static String bytes2BinaryStr(byte[] bArray) {
+
+        String outStr = "";
+        int pos = 0;
+        for (byte b : bArray) {
+            //高四位
+            pos = (b & 0xF0) >> 4;
+            outStr += binaryArray[pos];
+            //低四位
+            pos = b & 0x0F;
+            outStr += binaryArray[pos];
         }
-        return str;
+        return outStr;
     }
 
     /**
      * 16进制转换成为string类型字符串
+     *
      * @param s
      * @return
      */
@@ -95,17 +80,50 @@ public class ASCIIUtil {
         return s;
     }
 
-    public static String hexString2binaryString(String hexString) {
-        if (hexString == null || hexString.length() % 2 != 0)
-            return null;
-        String bString = "", tmp;
-        for (int i = 0; i < hexString.length(); i++) {
-            tmp = "0000" + Integer.toBinaryString(Integer.parseInt(hexString.substring(i, i + 1), 16));
-            bString += tmp.substring(tmp.length() - 4);
+    /**
+     * 将十六进制转换为字节数组
+     *
+     * @param hexString
+     * @return
+     */
+    public static byte[] HexStringToBinary(String hexString) {
+        //hexString的长度对2取整,作为bytes的长度
+        int len = hexString.length() / 2;
+        byte[] bytes = new byte[len];
+        byte high = 0;//字节高四位
+        byte low = 0;//字节低四位
+
+        for (int i = 0; i < len; i++) {
+            //右移四位得到高位
+            high = (byte) ((hexStr.indexOf(hexString.charAt(2 * i))) << 4);
+            low = (byte) hexStr.indexOf(hexString.charAt(2 * i + 1));
+            bytes[i] = (byte) (high | low);//高地位做或运算
         }
-        return bString;
+        return bytes;
     }
 
+
+    /**
+     * 字符串转化成为16进制字符串
+     *
+     * @param s
+     * @return
+     */
+    public static String strTo16(String s) {
+        String str = "";
+        for (int i = 0; i < s.length(); i++) {
+            int ch = (int) s.charAt(i);
+            String s4 = Integer.toHexString(ch);
+            str = str + s4;
+        }
+        return str;
+    }
+
+    /**
+     * 二进制字符串转化为16进制字符串
+     * @param bString
+     * @return
+     */
     public static String binaryString2hexString(String bString) {
         if (bString == null || bString.equals("") || bString.length() % 8 != 0)
             return null;
@@ -122,92 +140,74 @@ public class ASCIIUtil {
     }
 
     /**
-     *
+     * 转换为二进制字符串
      * @param str
-     * @return 转换为二进制字符串
+     * @return
      */
-    public static String bytes2BinaryStr(byte[] bArray){
+    public static String toBinary(int str) {
+        return Integer.toBinaryString(str);
+    }
 
-        String outStr = "";
-        int pos = 0;
-        for(byte b:bArray){
-            //高四位
-            pos = (b&0xF0)>>4;
-            outStr+=binaryArray[pos];
-            //低四位
-            pos=b&0x0F;
-            outStr+=binaryArray[pos];
-        }
-        return outStr;
 
-    }
     /**
-     *
-     * @param bytes
-     * @return 将二进制转换为十六进制字符输出
+     * 将int 转成对应的16进制字符串
+     * @param b
+     * @return
      */
-    public static String BinaryToHexString(byte[] bytes){
-
-        String result = "";
-        String hex = "";
-        for(int i=0;i<bytes.length;i++){
-            //字节高4位
-            hex = String.valueOf(hexStr.charAt((bytes[i]&0xF0)>>4));
-            //字节低4位
-            hex += String.valueOf(hexStr.charAt(bytes[i]&0x0F));
-            result +=hex+" ";
-        }
-        return result;
+    //使用1字节就可以表示b
+    public static String numToHex8(int b) {
+        //2表示需要两个16进行数
+        return String.format("%02x", b);
     }
+
     /**
-     *
-     * @param hexString
-     * @return 将十六进制转换为字节数组
+     * 将int 转成对应的16进制字符串
+     * @param b
+     * @return
      */
-    public static byte[] HexStringToBinary(String hexString){
-        //hexString的长度对2取整,作为bytes的长度
-        int len = hexString.length()/2;
-        byte[] bytes = new byte[len];
-        byte high = 0;//字节高四位
-        byte low = 0;//字节低四位
-
-        for(int i=0;i<len;i++){
-            //右移四位得到高位
-            high = (byte)((hexStr.indexOf(hexString.charAt(2*i)))<<4);
-            low = (byte)hexStr.indexOf(hexString.charAt(2*i+1));
-            bytes[i] = (byte) (high|low);//高地位做或运算
-        }
-        return bytes;
-    }
-
-
-    public static String getOKFeedback(String[] str){
-        StringBuffer startBitBuffer = new StringBuffer(str[0]).append(str[1]).append(str[2]).append(str[3]);
-        StringBuffer okBuffer = new StringBuffer(startBitBuffer).append(numToHex16(11)).append(str[6]).append("00").append(strTo16("OK"));
-        okBuffer.append(makeChecksum(okBuffer.toString()));
-        return okBuffer.toString();
-    }
-
-    public static String getErrFeedback(String[] str){
-        StringBuffer startBitBuffer = new StringBuffer(str[0]).append(str[1]).append(str[2]).append(str[3]);
-        StringBuffer errorBuffer = new StringBuffer(startBitBuffer).append(numToHex16(13)).append(str[6]).append("00").append(strTo16("ERR")).append("00");
-        errorBuffer.append(makeChecksum(errorBuffer.toString()));
-        return errorBuffer.toString();
-    }
-
-    public static String getYGDeviceID(String[] str){
-        return new StringBuffer(str[8]).append(str[9]).append(str[10]).append(str[11]).append(str[12]).append(str[13]).append(str[14]).append(str[15]).toString();
+    //需要使用2字节表示b
+    public static String numToHex16(int b) {
+        return String.format("%04x", b);
     }
 
-    public static String getJGDeviceID(String[] str){
-        return new StringBuffer(str[8]).append(str[7]).append(str[10]).append(str[9]).toString();
-    }
-    public static String getFeedBackJGDeviceID(String[] str){
-        return new StringBuffer(str[7]).append(str[8]).append(str[9]).append(str[10]).toString();
+    /**
+     * 将int 转成对应的16进制字符串
+     * @param b
+     * @return
+     */
+    //需要使用4字节表示b
+    public static String numToHex32(int b) {
+        return String.format("%08x", b);
     }
 
-    public static String toBinary(int str) {
-        return Integer.toBinaryString(str);
+    /**
+     * 计算十六进制校验位
+     * @param data
+     * @return
+     */
+    public static String makeChecksum(String data) {
+        if (data == null || data.equals("")) {
+            return "";
+        }
+        int total = 0;
+        int len = data.length();
+        int num = 0;
+        while (num < len) {
+            String s = data.substring(num, num + 2);
+            total += Integer.parseInt(s, 16);
+            num = num + 2;
+        }
+        /**
+         * 用256求余最大是255,即16进制的FF
+         */
+        int mod = total % 256;
+        String hex = Integer.toHexString(mod);
+        len = hex.length();
+        // 如果不够校验位的长度,补0,这里用的是两位校验
+        if (len < 2) {
+            hex = "0" + hex;
+        }
+        return hex;
     }
 
 }

+ 38 - 0
wsm-common/src/main/java/com/wsm/common/util/DeviceUtil.java

@@ -0,0 +1,38 @@
+package com.wsm.common.util;
+
+public class DeviceUtil {
+
+    public static String[] turnToArray(String replace) {
+        String regex = "(.{2})";
+        replace = replace.replaceAll(regex, "$1,");
+        return replace.split(",");
+    }
+
+    public static String getOKFeedback(String[] str){
+        StringBuffer startBitBuffer = new StringBuffer(str[0]).append(str[1]).append(str[2]).append(str[3]);
+        StringBuffer okBuffer = new StringBuffer(startBitBuffer).append(ByteUtil.numToHex16(11)).append(str[6]).append("00").append(ByteUtil.strTo16("OK"));
+        okBuffer.append(ByteUtil.makeChecksum(okBuffer.toString()));
+        return okBuffer.toString();
+    }
+
+    public static String getErrFeedback(String[] str){
+        StringBuffer startBitBuffer = new StringBuffer(str[0]).append(str[1]).append(str[2]).append(str[3]);
+        StringBuffer errorBuffer = new StringBuffer(startBitBuffer).append(ByteUtil.numToHex16(13)).append(str[6]).append("00").append(ByteUtil.strTo16("ERR")).append("00");
+        errorBuffer.append(ByteUtil.makeChecksum(errorBuffer.toString()));
+        return errorBuffer.toString();
+    }
+
+    public static String getYGDeviceID(String[] str){
+        return new StringBuffer(str[8]).append(str[9]).append(str[10]).append(str[11]).append(str[12]).append(str[13]).append(str[14]).append(str[15]).toString();
+    }
+
+    public static String getJGDeviceID(String[] str){
+        return new StringBuffer(str[8]).append(str[7]).append(str[10]).append(str[9]).toString();
+    }
+    public static String getFeedBackJGDeviceID(String[] str){
+        return new StringBuffer(str[7]).append(str[8]).append(str[9]).append(str[10]).toString();
+    }
+
+
+
+}