Browse Source

MQTT协议

wanglt 7 tháng trước cách đây
mục cha
commit
715ba396f9

+ 109 - 57
admin/src/main/java/com/dcs/equipment/service/impl/MQTTServiceImpl.java

@@ -1,11 +1,15 @@
 package com.dcs.equipment.service.impl;
 
+import com.dcs.equipment.constants.ProtocolConstants;
 import com.dcs.equipment.domain.DeviceRequest;
 import com.dcs.equipment.service.ProtocolService;
 import org.eclipse.paho.client.mqttv3.*;
 import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.PreDestroy;
+import java.util.concurrent.*;
+
 import java.util.List;
 
 /**
@@ -14,6 +18,7 @@ import java.util.List;
  */
 @Service("mqttService")
 public class MQTTServiceImpl implements ProtocolService {
+    private final ExecutorService executor = Executors.newSingleThreadExecutor();
     @Override
     public List<Object> getValues(DeviceRequest request) {
         return null;
@@ -21,69 +26,116 @@ public class MQTTServiceImpl implements ProtocolService {
 
     @Override
     public boolean setValue(DeviceRequest request) {
-        String broker = "tcp://" + request.getIpAddress() + ":" + request.getPort();
-        String topic = request.getResource();
-        String clientId = "java_client_" + System.currentTimeMillis();
-        String username = request.getData().get(1).toString();
-        String password = request.getData().get(2).toString();
-        Integer qos = request.getLengthOrQos();
-
-        try {
-            MqttClient client = new MqttClient(broker, clientId, new MemoryPersistence());
-
-            MqttConnectOptions options = new MqttConnectOptions();
-            options.setCleanSession(true);
-            options.setUserName(username);
-            options.setPassword(password.toCharArray());
-
-            // 设置回调,用于接收消息
-            client.setCallback(new MqttCallback() {
-                @Override
-                public void connectionLost(Throwable cause) {
-                    System.out.println("连接丢失: " + cause.getMessage());
-                }
+        if (request == null || request.getProtocol() == null || !request.getProtocol().equals(ProtocolConstants.MQTT)) {
+            return false;
+        }
+        if (request.getData() == null || request.getData().size() < 3) {
+            return false;
+        }
 
-                @Override
-                public void messageArrived(String topic, MqttMessage message) {
-                    System.out.println("接收到设备回复: " + new String(message.getPayload()));
+        // 提交任务到线程池
+        Future<Boolean> future = executor.submit(() -> {
+            String broker = "tcp://" + request.getIpAddress() + ":" + request.getPort();
+            String topic = request.getResource();
+            String clientId = "java_client_" + System.currentTimeMillis();
+            String username = request.getData().get(1).toString();
+            String password = request.getData().get(2).toString();
+            Integer qos = request.getLengthOrQos();
+            MqttClient client = null;
+
+            try {
+                client = new MqttClient(broker, clientId, new MemoryPersistence());
+                MqttConnectOptions options = new MqttConnectOptions();
+                options.setCleanSession(true);
+                options.setUserName(username);
+                options.setPassword(password.toCharArray());
+
+                client.setCallback(new MqttCallback() {
+                    @Override
+                    public void connectionLost(Throwable cause) {
+                        System.out.println("连接丢失: " + cause.getMessage());
+                    }
+
+                    @Override
+                    public void messageArrived(String topic, MqttMessage message) {
+                        System.out.println("接收到设备回复: " + new String(message.getPayload()));
+                    }
+
+                    @Override
+                    public void deliveryComplete(IMqttDeliveryToken token) {
+                        System.out.println("消息已成功发送");
+                    }
+                });
+
+                client.connect(options);
+                System.out.println("连接成功");
+                client.subscribe(topic, qos);
+                System.out.println("已订阅 topic: " + topic);
+
+                // 发布消息
+                String jsonPayload = request.getData().get(0).toString();
+                MqttMessage message = new MqttMessage(jsonPayload.getBytes());
+                message.setQos(qos);
+                client.publish(topic, message);
+                System.out.println("已发送 JSON 消息: " + jsonPayload);
+
+                // 模拟等待回复(实际应根据业务需求调整)
+                Thread.sleep(30000);
+                return true;
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt(); // 恢复中断状态
+                System.out.println("任务被中断,执行清理");
+                if (client != null) {
+                    try {
+                        if (client.isConnected()) {
+                            client.disconnect();
+                        }
+                        client.close();
+                    } catch (MqttException ex) {
+                        ex.printStackTrace();
+                        System.err.println("MQTT 客户端关闭失败: " + e.getMessage());
+                    }
                 }
-
-                @Override
-                public void deliveryComplete(IMqttDeliveryToken token) {
-                    // 可选:消息确认送达后触发
-                    System.out.println("消息已成功发送");
+                return false;
+            } catch (Exception e) {
+                e.printStackTrace();
+                return false;
+            } finally {
+                if (client != null) {
+                    try {
+                        if (client.isConnected()) {
+                            client.disconnect();
+                        }
+                        client.close(); // 即使未连接也调用 close()
+                    } catch (MqttException e) {
+                        // 记录日志,避免吞没异常
+                        System.err.println("MQTT 客户端关闭失败: " + e.getMessage());
+                    }
                 }
-            });
-
-            client.connect(options);
-            System.out.println("连接成功");
-
-            // 订阅 topic 等待设备响应
-            client.subscribe(topic, qos);
-            System.out.println("已订阅 topic: " + topic);
-
-            // 构建 JSON 消息并发布
-            Object o = request.getData().get(0);
-            String jsonPayload = o.toString();
-            MqttMessage message = new MqttMessage(jsonPayload.getBytes());
-            message.setQos(qos);
-            client.publish(topic, message);
-            System.out.println("已发送 JSON 消息: " + jsonPayload);
-
-            // 保持连接等待回复(例如 30 秒)
-//            System.out.println("等待设备回复中...");
-//            Thread.sleep(30000); // 可根据需要调整等待时间
-
-            // 关闭连接
-            client.disconnect();
-            client.close();
-            System.out.println("连接已断开");
-            return true;
+            }
+        });
 
+        // 阻塞等待结果(或设置超时)
+        try {
+            return future.get(60, TimeUnit.SECONDS); // 总超时时间(连接+等待回复)
         } catch (Exception e) {
-            e.printStackTrace();
+            future.cancel(true); // 超时后取消任务
+            return false;
+        }
+    }
+
+    // 关闭线程池(在应用终止时调用)
+    @PreDestroy
+    public void shutdown() {
+        executor.shutdown();
+        try {
+            if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
+                executor.shutdownNow();
+            }
+        } catch (InterruptedException e) {
+            executor.shutdownNow();
+            Thread.currentThread().interrupt();
         }
-        return false;
     }
 
     @Override

+ 4 - 0
admin/src/main/java/com/dcs/equipment/service/impl/ModbusTcpServiceImpl.java

@@ -3,6 +3,7 @@ package com.dcs.equipment.service.impl;
 //import com.dcs.dcs.domain.vo.EquipmentParamFormVo;
 
 import com.dcs.equipment.constants.ModbusConstants;
+import com.dcs.equipment.constants.ProtocolConstants;
 import com.dcs.equipment.domain.DeviceRequest;
 import com.dcs.equipment.exception.device.DeviceException;
 import com.dcs.equipment.exception.device.DeviceIOException;
@@ -164,6 +165,9 @@ public class ModbusTcpServiceImpl implements ProtocolService {
 
     @Override
     public boolean setValue(DeviceRequest request) {
+        if (request==null || request.getProtocol()==null || !request.getProtocol().equals(ProtocolConstants.MODBUS_TCP)) {
+            return false;
+        }
         try {
             switch (request.getDataType()) {
                 case ModbusConstants.COIL_DATA_TYPE:

+ 7 - 15
ui/src/assets/dcs/iconfont_colour_hnyz/iconfont.css

@@ -2,9 +2,9 @@
   font-family: "iconfont-hnyz-colour"; /* Project id 4940749 */
   /* Color fonts */
   src: 
-       url('iconfont.woff2?t=1755657745508') format('woff2'),
-       url('iconfont.woff?t=1755657745508') format('woff'),
-       url('iconfont.ttf?t=1755657745508') format('truetype');
+       url('iconfont.woff2?t=1758184209249') format('woff2'),
+       url('iconfont.woff?t=1758184209249') format('woff'),
+       url('iconfont.ttf?t=1758184209249') format('truetype');
 }
 
 .iconfont-hnyz-colour {
@@ -15,6 +15,10 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-hnyz-coloura-Frame20:before {
+  content: "\e611";
+}
+
 .icon-hnyz-colourflowFan:before {
   content: "\e9c8";
 }
@@ -91,10 +95,6 @@
   content: "\e90b";
 }
 
-.icon-hnyz-colourkaomianjin-1:before {
-  content: "\e607";
-}
-
 .icon-hnyz-colourdosingMachine:before {
   content: "\e64b";
 }
@@ -135,11 +135,3 @@
   content: "\e602";
 }
 
-.icon-hnyz-colourbeng2_L:before {
-  content: "\e601";
-}
-
-.icon-hnyz-colourbeng2_R:before {
-  content: "\e640";
-}
-

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
ui/src/assets/dcs/iconfont_colour_hnyz/iconfont.js


+ 7 - 21
ui/src/assets/dcs/iconfont_colour_hnyz/iconfont.json

@@ -5,6 +5,13 @@
   "css_prefix_text": "icon-hnyz-colour",
   "description": "湖南多色图标",
   "glyphs": [
+    {
+      "icon_id": "45584092",
+      "name": "回转窑",
+      "font_class": "a-Frame20",
+      "unicode": "e611",
+      "unicode_decimal": 58897
+    },
     {
       "icon_id": "12234955",
       "name": "轴流风机",
@@ -138,13 +145,6 @@
       "unicode": "e90b",
       "unicode_decimal": 59659
     },
-    {
-      "icon_id": "44523290",
-      "name": "螺旋输送机",
-      "font_class": "kaomianjin-1",
-      "unicode": "e607",
-      "unicode_decimal": 58887
-    },
     {
       "icon_id": "28953833",
       "name": "加药机",
@@ -214,20 +214,6 @@
       "font_class": "stockBin",
       "unicode": "e602",
       "unicode_decimal": 58882
-    },
-    {
-      "icon_id": "44519604",
-      "name": "beng2_L",
-      "font_class": "beng2_L",
-      "unicode": "e601",
-      "unicode_decimal": 58881
-    },
-    {
-      "icon_id": "31572037",
-      "name": "泵",
-      "font_class": "beng2_R",
-      "unicode": "e640",
-      "unicode_decimal": 58944
     }
   ]
 }

BIN
ui/src/assets/dcs/iconfont_colour_hnyz/iconfont.ttf


BIN
ui/src/assets/dcs/iconfont_colour_hnyz/iconfont.woff


BIN
ui/src/assets/dcs/iconfont_colour_hnyz/iconfont.woff2


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
ui/src/assets/dcs/rotarykiln.svg


+ 77 - 0
ui/src/components/GeneralComponents/RotaryKiln.vue

@@ -0,0 +1,77 @@
+<template>
+  <div class="tank_body" :style="{ width: dimensions.width + 'px', height: dimensions.height + 'px' }">
+    <!-- svg 图标 -->
+    <img :src="rotarykiln" class="tank_svg" />
+
+    <!-- 标题 -->
+    <div class="tank_title" v-if="title" :style="titleStyle">
+      {{ title }}
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { computed } from 'vue'
+import rotarykiln from '@/assets/dcs/rotarykiln.svg'
+
+const props = defineProps({
+  iconSize: { type: Number, default: 200 },
+  title: { type: String, default: '' },
+  iconWidth: { type: Number, default: null },
+  iconHeight: { type: Number, default: null },
+})
+
+// 计算最终宽高
+const dimensions = computed(() => {
+  const base = props.iconSize
+  if (props.iconWidth && props.iconHeight) {
+    return { width: props.iconWidth, height: props.iconHeight }
+  }
+  if (props.iconWidth) {
+    return { width: props.iconWidth, height: props.iconWidth }
+  }
+  if (props.iconHeight) {
+    return { width: props.iconHeight, height: props.iconHeight }
+  }
+  return { width: base, height: base }
+})
+
+// 动态标题样式
+const titleStyle = computed(() => {
+  const { width } = dimensions.value
+  const len = props.title?.length || 0
+  let baseSize
+  if (len <= 4) baseSize = width * 0.10
+  else if (len <= 8) baseSize = width * 0.09
+  else if (len <= 12) baseSize = width * 0.08
+  else baseSize = width * 0.06
+
+  const finalSize = Math.min(baseSize, 30)
+  return {
+    fontSize: `${finalSize}px`,
+    position: 'absolute',
+    top: '21%',
+    left: '50%',
+    transform: 'translate(-50%, -50%)',
+    color: '#e65100',
+    fontWeight: 'bold',
+    zIndex: 20,
+    pointerEvents: 'none',
+    textAlign: 'center',
+    whiteSpace: 'nowrap',
+  }
+})
+</script>
+
+<style scoped lang="scss">
+.tank_body {
+  text-align: center;
+  position: relative;
+
+  .tank_svg {
+    width: 100%;
+    height: 100%;
+    display: block;
+  }
+}
+</style>

+ 1 - 0
ui/src/hooks/useComponentHelper.js

@@ -39,6 +39,7 @@ const componentMap = {
     BeltFilter: lazyComponent(() => import('@/components/GeneralComponents/BeltFilterComponent.vue')),//平真空带式过滤器
     Arrow2: lazyComponent(() => import('@/components/GeneralComponents/Arrow2Component.vue')),//箭头2
     BrineHollowTank: lazyComponent(() => import('@/components/GeneralComponents/BrineHollowTankComponent.vue')),//卤水罐
+    RotaryKiln: lazyComponent(() => import('@/components/GeneralComponents/RotaryKiln.vue')),//回转窑
 };
 
 //获取注册组件

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác