From ab389a5a6b329b15a655340ba7b87bce7fd7871d Mon Sep 17 00:00:00 2001
From: huang <1532065656@qq.com>
Date: 星期三, 24 十二月 2025 17:16:19 +0800
Subject: [PATCH] 添加新增设备自动生成编码

---
 mes-processes/mes-plcSend/src/main/java/com/mes/plc/client/impl/ModbusPlcClient.java |  370 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 325 insertions(+), 45 deletions(-)

diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/plc/client/impl/ModbusPlcClient.java b/mes-processes/mes-plcSend/src/main/java/com/mes/plc/client/impl/ModbusPlcClient.java
index 03f03c7..0a12508 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/plc/client/impl/ModbusPlcClient.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/plc/client/impl/ModbusPlcClient.java
@@ -1,13 +1,15 @@
 package com.mes.plc.client.impl;
 
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.mes.connect.modbus.ModbusTcpClient;
 import com.mes.device.entity.DeviceConfig;
+import com.mes.device.util.ConfigJsonHelper;
 import com.mes.plc.client.PlcClient;
 import lombok.extern.slf4j.Slf4j;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
+import java.io.IOException;
+import java.util.*;
 
 /**
  * Modbus鍗忚PLC瀹㈡埛绔疄鐜�
@@ -20,34 +22,44 @@
  */
 @Slf4j
 public class ModbusPlcClient implements PlcClient {
-    
+
     // PLC IP鍦板潃
     private final String plcIp;
-    
+
     // PLC绔彛
     private final int plcPort;
-    
+
     // 浠庣珯鍦板潃
     private final int unitId;
-    
+
+    // 璁惧閰嶇疆
+    private final DeviceConfig device;
+
     // Modbus瀹㈡埛绔疄渚�
     private ModbusTcpClient modbusClient;
-    
+
     // 杩炴帴鐘舵��
     private boolean connected = false;
-    
+
     // 瓒呮椂鏃堕棿锛堟绉掞級
     private int timeout = 5000;
-    
+
+    // ObjectMapper鐢ㄤ簬JSON瑙f瀽
+    private final ObjectMapper objectMapper = new ObjectMapper();
+
+    // 鍦板潃鏄犲皠缂撳瓨锛氬瓧娈靛悕 -> Modbus鍦板潃
+    private Map<String, String> addressMappingCache;
+
     /**
      * 鏋勯�犲嚱鏁�
      *
      * @param device 璁惧閰嶇疆
      */
     public ModbusPlcClient(DeviceConfig device) {
+        this.device = device;
         this.plcIp = device.getPlcIp();
         this.plcPort = device.getPlcPort() != null ? device.getPlcPort() : 502;
-        
+
         // 浠庨厤缃腑鑾峰彇浠庣珯鍦板潃锛岄粯璁�1
         int unitIdValue = 1;
         try {
@@ -64,8 +76,11 @@
             log.warn("瑙f瀽unitId澶辫触锛屼娇鐢ㄩ粯璁ゅ��1: deviceId={}", device.getId(), e);
         }
         this.unitId = unitIdValue;
+
+        // 鍒濆鍖栧湴鍧�鏄犲皠
+        this.addressMappingCache = loadAddressMapping();
     }
-    
+
     /**
      * 瑙f瀽璁惧鐨別xtraParams
      *
@@ -74,29 +89,126 @@
      */
     private Map<String, Object> parseExtraParams(String extraParamsJson) {
         if (extraParamsJson == null || extraParamsJson.isEmpty()) {
-            return null;
-        }
-        
-        try {
-            // 杩欓噷绠�鍖栧鐞嗭紝瀹為檯椤圭洰涓簲璇ヤ娇鐢↗ackson鎴朑son瑙f瀽
-            // 鐢变簬椤圭洰涓凡鏈塐bjectMapper锛岃繖閲屾殏鏃惰繑鍥炵┖Map锛屽悗缁畬鍠�
             return new HashMap<>();
+        }
+
+        try {
+            TypeReference<Map<String, Object>> typeRef = new TypeReference<Map<String, Object>>() {};
+            return objectMapper.readValue(extraParamsJson, typeRef);
         } catch (Exception e) {
             log.error("瑙f瀽extraParams澶辫触: {}", extraParamsJson, e);
-            return null;
+            return new HashMap<>();
         }
     }
-    
+
+    /**
+     * 鍔犺浇鍦板潃鏄犲皠閰嶇疆锛堜粠configJson鎴杄xtraParams.addressMapping锛�
+     *
+     * @return 瀛楁鍚� -> Modbus鍦板潃鐨勬槧灏�
+     */
+    private Map<String, String> loadAddressMapping() {
+        Map<String, String> mapping = new HashMap<>();
+
+        try {
+            // 1. 浼樺厛浠巆onfigJson鑾峰彇
+            Map<String, Object> configParams = ConfigJsonHelper.parseToMap(device.getConfigJson(), objectMapper);
+            if (!configParams.isEmpty()) {
+                for (Map.Entry<String, Object> entry : configParams.entrySet()) {
+                    String fieldName = entry.getKey();
+                    Object addressObj = entry.getValue();
+                    if (addressObj != null) {
+                        mapping.put(fieldName, String.valueOf(addressObj));
+                    }
+                }
+                if (!mapping.isEmpty()) {
+                    log.info("浠巆onfigJson鍔犺浇Modbus鍦板潃鏄犲皠鎴愬姛: deviceId={}, count={}", device.getId(), mapping.size());
+                    return mapping;
+                }
+            }
+
+            // 2. 浠巈xtraParams.addressMapping鑾峰彇
+            Map<String, Object> extraParams = parseExtraParams(device.getExtraParams());
+            Object addressMappingObj = extraParams.get("addressMapping");
+            if (addressMappingObj != null) {
+                if (addressMappingObj instanceof Map) {
+                    @SuppressWarnings("unchecked")
+                    Map<String, Object> addrMap = (Map<String, Object>) addressMappingObj;
+                    for (Map.Entry<String, Object> entry : addrMap.entrySet()) {
+                        mapping.put(entry.getKey(), String.valueOf(entry.getValue()));
+                    }
+                } else if (addressMappingObj instanceof String) {
+                    // 濡傛灉鏄疛SON瀛楃涓诧紝瑙f瀽瀹�
+                    TypeReference<Map<String, Object>> typeRef = new TypeReference<Map<String, Object>>() {};
+                    Map<String, Object> addrMap = objectMapper.readValue((String) addressMappingObj, typeRef);
+                    for (Map.Entry<String, Object> entry : addrMap.entrySet()) {
+                        mapping.put(entry.getKey(), String.valueOf(entry.getValue()));
+                    }
+                }
+                if (!mapping.isEmpty()) {
+                    log.info("浠巈xtraParams.addressMapping鍔犺浇Modbus鍦板潃鏄犲皠鎴愬姛: deviceId={}, count={}", device.getId(), mapping.size());
+                    return mapping;
+                }
+            }
+
+            log.warn("鏈壘鍒癕odbus鍦板潃鏄犲皠閰嶇疆: deviceId={}", device.getId());
+        } catch (Exception e) {
+            log.error("鍔犺浇Modbus鍦板潃鏄犲皠澶辫触: deviceId={}", device.getId(), e);
+        }
+
+        return mapping;
+    }
+
+    /**
+     * 鑾峰彇瀛楁瀵瑰簲鐨凪odbus鍦板潃
+     *
+     * @param fieldName 瀛楁鍚�
+     * @return Modbus鍦板潃锛堟牸寮忥細鍔熻兘鐮�.瀵勫瓨鍣ㄥ湴鍧�锛屽 "3.40001"锛�
+     */
+    private String getModbusAddress(String fieldName) {
+        String address = addressMappingCache.get(fieldName);
+        if (address == null || address.isEmpty()) {
+            log.warn("瀛楁 {} 鏈壘鍒癕odbus鍦板潃鏄犲皠: deviceId={}", fieldName, device.getId());
+            return null;
+        }
+        return address;
+    }
+
+    /**
+     * 鎺ㄦ柇鏁版嵁绫诲瀷锛堟牴鎹瓧娈靛悕鎴栧�硷級
+     */
+    private String inferDataType(String fieldName, Object value) {
+        if (value == null) {
+            // 鏍规嵁瀛楁鍚嶆帹鏂�
+            String lowerName = fieldName.toLowerCase();
+            if (lowerName.contains("float") || lowerName.contains("real")) {
+                return "float";
+            } else if (lowerName.contains("string") || lowerName.contains("str") || lowerName.contains("id")) {
+                return "string";
+            }
+            return "int"; // 榛樿int
+        }
+
+        // 鏍规嵁鍊肩被鍨嬫帹鏂�
+        if (value instanceof Float || value instanceof Double) {
+            return "float";
+        } else if (value instanceof String) {
+            return "string";
+        } else if (value instanceof Number) {
+            return "int";
+        }
+        return "int";
+    }
+
     @Override
     public boolean connect() {
         try {
             if (modbusClient != null && isConnected()) {
                 return true;
             }
-            
+
             // 鍒涘缓Modbus瀹㈡埛绔疄渚�
             this.modbusClient = new ModbusTcpClient(this.plcIp, this.plcPort, this.unitId);
-            
+
             // 杩炴帴PLC
             this.modbusClient.connect();
             this.connected = true;
@@ -108,7 +220,7 @@
             return false;
         }
     }
-    
+
     @Override
     public void disconnect() {
         try {
@@ -123,56 +235,169 @@
             this.modbusClient = null;
         }
     }
-    
+
     @Override
     public Map<String, Object> readAllData() {
         if (!isConnected() && !connect()) {
             log.error("Modbus PLC鏈繛鎺ワ紝鏃犳硶璇诲彇鏁版嵁: {}:{}", this.plcIp, this.plcPort);
             return Collections.emptyMap();
         }
-        
+
         try {
-            // TODO: 瀹炵幇Modbus璇诲彇鎵�鏈夋暟鎹�
-            // 杩欓噷鏆傛椂杩斿洖绌篗ap锛屽悗缁畬鍠�
-            log.warn("Modbus readAllData鏈疄鐜帮紝杩斿洖绌篗ap");
-            return new HashMap<>();
+            if (addressMappingCache.isEmpty()) {
+                log.warn("Modbus鍦板潃鏄犲皠涓虹┖锛屾棤娉曡鍙栨墍鏈夋暟鎹�: deviceId={}", device.getId());
+                return Collections.emptyMap();
+            }
+
+            // 璇诲彇鎵�鏈夐厤缃殑瀛楁
+            Map<String, Object> result = new HashMap<>();
+            for (String fieldName : addressMappingCache.keySet()) {
+                try {
+                    Object value = readFieldValue(fieldName);
+                    if (value != null) {
+                        result.put(fieldName, value);
+                    }
+                } catch (Exception e) {
+                    log.warn("璇诲彇瀛楁澶辫触: fieldName={}, deviceId={}, error={}", fieldName, device.getId(), e.getMessage());
+                }
+            }
+
+            log.info("Modbus璇诲彇鎵�鏈夋暟鎹垚鍔�: deviceId={}, fieldCount={}", device.getId(), result.size());
+            return result;
         } catch (Exception e) {
             log.error("Modbus PLC璇诲彇鎵�鏈夋暟鎹け璐�: {}:{}", this.plcIp, this.plcPort, e);
             this.connected = false;
             return Collections.emptyMap();
         }
     }
-    
+
     @Override
     public Map<String, Object> readData(String... fields) {
         if (!isConnected() && !connect()) {
             log.error("Modbus PLC鏈繛鎺ワ紝鏃犳硶璇诲彇鏁版嵁: {}:{}", this.plcIp, this.plcPort);
             return Collections.emptyMap();
         }
-        
+
+        if (fields == null || fields.length == 0) {
+            return readAllData();
+        }
+
         try {
-            // TODO: 瀹炵幇Modbus璇诲彇鎸囧畾瀛楁鏁版嵁
-            // 杩欓噷鏆傛椂杩斿洖绌篗ap锛屽悗缁畬鍠�
-            log.warn("Modbus readData鏈疄鐜帮紝杩斿洖绌篗ap");
-            return new HashMap<>();
+            Map<String, Object> result = new HashMap<>();
+            for (String fieldName : fields) {
+                if (fieldName == null || fieldName.isEmpty()) {
+                    continue;
+                }
+                try {
+                    Object value = readFieldValue(fieldName);
+                    if (value != null) {
+                        result.put(fieldName, value);
+                    }
+                } catch (Exception e) {
+                    log.warn("璇诲彇瀛楁澶辫触: fieldName={}, deviceId={}, error={}", fieldName, device.getId(), e.getMessage());
+                }
+            }
+
+            log.info("Modbus璇诲彇鎸囧畾瀛楁鏁版嵁鎴愬姛: deviceId={}, fields={}, resultCount={}",
+                    device.getId(), Arrays.toString(fields), result.size());
+            return result;
         } catch (Exception e) {
             log.error("Modbus PLC璇诲彇鏁版嵁澶辫触: {}:{}", this.plcIp, this.plcPort, e);
             this.connected = false;
             return Collections.emptyMap();
         }
     }
-    
+
+    /**
+     * 璇诲彇鍗曚釜瀛楁鐨勫��
+     */
+    private Object readFieldValue(String fieldName) throws IOException {
+        String address = getModbusAddress(fieldName);
+        if (address == null) {
+            return null;
+        }
+
+        // 鏍规嵁瀛楁鍚嶆帹鏂暟鎹被鍨嬶紙浼樺厛浠庨厤缃腑鑾峰彇锛�
+        String dataType = inferDataType(fieldName, null);
+
+        // 浠巈xtraParams涓幏鍙栧瓧娈电殑鏁版嵁绫诲瀷閰嶇疆
+        Map<String, Object> extraParams = parseExtraParams(device.getExtraParams());
+        @SuppressWarnings("unchecked")
+        Map<String, Object> fieldConfigs = (Map<String, Object>) extraParams.get("fieldConfigs");
+        if (fieldConfigs != null) {
+            @SuppressWarnings("unchecked")
+            Map<String, Object> fieldConfig = (Map<String, Object>) fieldConfigs.get(fieldName);
+            if (fieldConfig != null && fieldConfig.get("dataType") != null) {
+                dataType = String.valueOf(fieldConfig.get("dataType"));
+            }
+        }
+
+        // 鏍规嵁鏁版嵁绫诲瀷璇诲彇
+        switch (dataType.toLowerCase()) {
+            case "float":
+            case "real":
+                return modbusClient.readFloat(address);
+            case "string":
+            case "str":
+                // 瀛楃涓查渶瑕佹寚瀹氶暱搴︼紝榛樿32瀛楃
+                int stringLength = 32;
+                if (fieldConfigs != null) {
+                    @SuppressWarnings("unchecked")
+                    Map<String, Object> fieldConfig = (Map<String, Object>) fieldConfigs.get(fieldName);
+                    if (fieldConfig != null && fieldConfig.get("length") != null) {
+                        stringLength = ((Number) fieldConfig.get("length")).intValue();
+                    }
+                }
+                return modbusClient.readString(address, stringLength);
+            case "int":
+            case "integer":
+            case "word":
+            default:
+                return modbusClient.readRegister(address);
+        }
+    }
+
     @Override
     public boolean writeData(Map<String, Object> data) {
         if (!isConnected() && !connect()) {
             log.error("Modbus PLC鏈繛鎺ワ紝鏃犳硶鍐欏叆鏁版嵁: {}:{}", this.plcIp, this.plcPort);
             return false;
         }
-        
+
+        if (data == null || data.isEmpty()) {
+            log.warn("鍐欏叆鏁版嵁涓虹┖锛岃烦杩囨搷浣�: deviceId={}", device.getId());
+            return true;
+        }
+
         try {
-            // TODO: 瀹炵幇Modbus鍐欏叆鏁版嵁
-            // 杩欓噷鏆傛椂杩斿洖true锛屽悗缁畬鍠�
-            log.warn("Modbus writeData鏈疄鐜帮紝杩斿洖鎴愬姛");
+            int successCount = 0;
+            int failCount = 0;
+
+            for (Map.Entry<String, Object> entry : data.entrySet()) {
+                String fieldName = entry.getKey();
+                Object value = entry.getValue();
+
+                if (value == null) {
+                    continue; // 璺宠繃null鍊�
+                }
+
+                try {
+                    writeFieldValue(fieldName, value);
+                    successCount++;
+                } catch (Exception e) {
+                    log.error("鍐欏叆瀛楁澶辫触: fieldName={}, value={}, deviceId={}, error={}",
+                            fieldName, value, device.getId(), e.getMessage());
+                    failCount++;
+                }
+            }
+
+            if (failCount > 0) {
+                log.warn("Modbus鍐欏叆鏁版嵁閮ㄥ垎澶辫触: deviceId={}, success={}, fail={}",
+                        device.getId(), successCount, failCount);
+                return false;
+            }
+
+            log.info("Modbus鍐欏叆鏁版嵁鎴愬姛: deviceId={}, fieldCount={}", device.getId(), successCount);
             return true;
         } catch (Exception e) {
             log.error("Modbus PLC鍐欏叆鏁版嵁澶辫触: {}:{}", this.plcIp, this.plcPort, e);
@@ -180,7 +405,63 @@
             return false;
         }
     }
-    
+
+    /**
+     * 鍐欏叆鍗曚釜瀛楁鐨勫��
+     */
+    private void writeFieldValue(String fieldName, Object value) throws IOException {
+        String address = getModbusAddress(fieldName);
+        if (address == null) {
+            throw new IllegalArgumentException("瀛楁 " + fieldName + " 鏈壘鍒癕odbus鍦板潃鏄犲皠");
+        }
+
+        // 鏍规嵁鍊肩被鍨嬫帹鏂暟鎹被鍨�
+        String dataType = inferDataType(fieldName, value);
+
+        // 浠巈xtraParams涓幏鍙栧瓧娈电殑鏁版嵁绫诲瀷閰嶇疆
+        Map<String, Object> extraParams = parseExtraParams(device.getExtraParams());
+        @SuppressWarnings("unchecked")
+        Map<String, Object> fieldConfigs = (Map<String, Object>) extraParams.get("fieldConfigs");
+        if (fieldConfigs != null) {
+            @SuppressWarnings("unchecked")
+            Map<String, Object> fieldConfig = (Map<String, Object>) fieldConfigs.get(fieldName);
+            if (fieldConfig != null && fieldConfig.get("dataType") != null) {
+                dataType = String.valueOf(fieldConfig.get("dataType"));
+            }
+        }
+
+        // 鏍规嵁鏁版嵁绫诲瀷鍐欏叆
+        switch (dataType.toLowerCase()) {
+            case "float":
+            case "real":
+                float floatValue;
+                if (value instanceof Number) {
+                    floatValue = ((Number) value).floatValue();
+                } else {
+                    floatValue = Float.parseFloat(String.valueOf(value));
+                }
+                modbusClient.writeFloat(address, floatValue);
+                break;
+            case "string":
+            case "str":
+                String stringValue = String.valueOf(value);
+                modbusClient.writeString(address, stringValue);
+                break;
+            case "int":
+            case "integer":
+            case "word":
+            default:
+                int intValue;
+                if (value instanceof Number) {
+                    intValue = ((Number) value).intValue();
+                } else {
+                    intValue = Integer.parseInt(String.valueOf(value));
+                }
+                modbusClient.writeRegister(address, intValue);
+                break;
+        }
+    }
+
     @Override
     public boolean isConnected() {
         try {
@@ -194,20 +475,19 @@
             return false;
         }
     }
-    
+
     @Override
     public String getPlcType() {
         return "MODBUS";
     }
-    
+
     @Override
     public int getTimeout() {
         return this.timeout;
     }
-    
+
     @Override
     public void setTimeout(int timeout) {
         this.timeout = timeout;
-        // ModbusTcpClient涓嶆敮鎸佺洿鎺ヨ缃秴鏃讹紝杩欓噷浠呰褰曡秴鏃舵椂闂�
     }
 }
\ No newline at end of file

--
Gitblit v1.8.0