From 8f3a85044b6e4b56a8dd0b104ca023933f1f129c Mon Sep 17 00:00:00 2001
From: huang <1532065656@qq.com>
Date: 星期三, 03 十二月 2025 16:58:36 +0800
Subject: [PATCH] 统一卧转立扫码、卧转立、大车、大理片笼的定时器逻辑和步骤状态;添加设备拓扑图清除数据、联机状态切换按钮,

---
 mes-processes/mes-plcSend/src/main/java/com/mes/service/impl/PlcDynamicDataServiceImpl.java |  576 ++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 480 insertions(+), 96 deletions(-)

diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/service/impl/PlcDynamicDataServiceImpl.java b/mes-processes/mes-plcSend/src/main/java/com/mes/service/impl/PlcDynamicDataServiceImpl.java
index 2a1b439..8831206 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/service/impl/PlcDynamicDataServiceImpl.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/service/impl/PlcDynamicDataServiceImpl.java
@@ -1,22 +1,29 @@
 package com.mes.service.impl;
 
 import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.github.xingshuangs.iot.common.enums.EDataType;
 import com.github.xingshuangs.iot.protocol.s7.serializer.S7Parameter;
-import com.mes.entity.PlcAddress;
+import com.mes.device.entity.DeviceConfig;
+import com.mes.device.util.ConfigJsonHelper;
 import com.mes.s7.enhanced.EnhancedS7Serializer;
 import com.mes.service.PlcDynamicDataService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
+import com.github.xingshuangs.iot.protocol.s7.serializer.S7Variable;
+
+import java.lang.reflect.Field;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 /**
  * PLC鍔ㄦ�佹暟鎹鍐欐湇鍔″疄鐜�
- * 閫氳繃PlcAddress涓殑addressMapping閰嶇疆鍔ㄦ�佽鍐欎换鎰忓瓧娈电粍鍚�
+ * 閫氳繃DeviceConfig涓殑configJson閰嶇疆鍔ㄦ�佽鍐欎换鎰忓瓧娈电粍鍚�
  * 
  * @author huang
  * @date 2025/11/05
@@ -24,27 +31,154 @@
 @Slf4j
 @Service
 public class PlcDynamicDataServiceImpl implements PlcDynamicDataService {
+    
+    private final ObjectMapper objectMapper = new ObjectMapper();
+    private static final TypeReference<Map<String, Object>> MAP_TYPE = new TypeReference<Map<String, Object>>() {};
 
     /**
-     * 鏍规嵁PlcAddress閰嶇疆鍜屽瓧娈靛悕绉拌鍙朠LC鏁版嵁
+     * 浠嶥eviceConfig涓彁鍙栧湴鍧�鏄犲皠閰嶇疆
      * 
-     * @param config PLC鍦板潃鏄犲皠閰嶇疆
-     * @param fieldNames 瑕佽鍙栫殑瀛楁鍚嶇О鍒楄〃
-     * @param s7Serializer S7搴忓垪鍖栧櫒
-     * @return 瀛楁鍚�->鍊� 鐨凪ap
+     * @param device 璁惧閰嶇疆
+     * @return 鍦板潃鏄犲皠JSON瀛楃涓�
      */
-    @Override
-    public Map<String, Object> readPlcData(PlcAddress config, List<String> fieldNames, EnhancedS7Serializer s7Serializer) {
-        if (config == null || config.getAddressMapping() == null) {
-            throw new IllegalArgumentException("PlcAddress閰嶇疆鎴朼ddressMapping涓嶈兘涓虹┖");
+    private String extractAddressMapping(DeviceConfig device) {
+        // configJson 鐜板湪浠呭瓨鏀惧瓧娈靛湴鍧�鏄犲皠锛堟暟缁勫舰寮忥級
+        Map<String, Object> configParams = ConfigJsonHelper.parseToMap(device.getConfigJson(), objectMapper);
+        if (!configParams.isEmpty()) {
+            try {
+                return objectMapper.writeValueAsString(configParams);
+            } catch (Exception e) {
+                log.warn("搴忓垪鍖朿onfigJson鍦板潃鏄犲皠澶辫触, deviceId={}", device.getId(), e);
+            }
         }
-
+        
+        // 鍏舵浠巈xtraParams涓幏鍙栵紙鍏煎鏃х粨鏋勶級
+        Map<String, Object> extraParams = parseExtraParams(device);
+        Object addressMapping = extraParams.get("addressMapping");
+        if (addressMapping != null) {
+            if (addressMapping instanceof String) {
+                return (String) addressMapping;
+            } else {
+                try {
+                    return objectMapper.writeValueAsString(addressMapping);
+                } catch (Exception e) {
+                    log.warn("搴忓垪鍖杄xtraParams.addressMapping澶辫触, deviceId={}", device.getId(), e);
+                }
+            }
+        }
+        
+        throw new IllegalArgumentException("璁惧閰嶇疆涓湭鎵惧埌addressMapping, deviceId=" + device.getId());
+    }
+    
+    /**
+     * 浠嶥eviceConfig涓彁鍙杁bArea
+     * 
+     * @param device 璁惧閰嶇疆
+     * @return dbArea
+     */
+    private String extractDbArea(DeviceConfig device) {
+        // 浠巈xtraParams.plcConfig涓幏鍙栵紙鏂扮粨鏋勶級
+        Map<String, Object> plcConfig = getPlcConfig(device);
+        Object dbArea = plcConfig.get("dbArea");
+        if (dbArea != null) {
+            return String.valueOf(dbArea);
+        }
+        
+        // 鍏煎鏃х粨鏋勶細extraParams鏍硅妭鐐�
+        Map<String, Object> extraParams = parseExtraParams(device);
+        Object legacyDbArea = extraParams.get("dbArea");
+        if (legacyDbArea != null) {
+            return String.valueOf(legacyDbArea);
+        }
+        
+        // 榛樿鍊�
+        return "DB12";
+    }
+    
+    /**
+     * 浠嶥eviceConfig涓彁鍙朾eginIndex
+     * 
+     * @param device 璁惧閰嶇疆
+     * @return beginIndex
+     */
+    private int extractBeginIndex(DeviceConfig device) {
+        // 浠巈xtraParams.plcConfig涓幏鍙�
+        Map<String, Object> plcConfig = getPlcConfig(device);
+        Object beginIndex = plcConfig.get("beginIndex");
+        if (beginIndex != null) {
+            return parseInteger(beginIndex);
+        }
+        
+        // 鍏煎鏃х粨鏋勶細extraParams鏍硅妭鐐�
+        Map<String, Object> extraParams = parseExtraParams(device);
+        Object legacyBeginIndex = extraParams.get("beginIndex");
+        if (legacyBeginIndex != null) {
+            return parseInteger(legacyBeginIndex);
+        }
+        
+        // 榛樿鍊�
+        return 0;
+    }
+    
+    private Map<String, Object> parseExtraParams(DeviceConfig device) {
+        if (device.getExtraParams() == null || device.getExtraParams().trim().isEmpty()) {
+            return Collections.emptyMap();
+        }
+        try {
+            return objectMapper.readValue(device.getExtraParams(), MAP_TYPE);
+        } catch (Exception e) {
+            log.warn("瑙f瀽璁惧extraParams澶辫触, deviceId={}", device.getId(), e);
+            return Collections.emptyMap();
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    private Map<String, Object> getPlcConfig(DeviceConfig device) {
+        Map<String, Object> extraParams = parseExtraParams(device);
+        Object plcConfig = extraParams.get("plcConfig");
+        if (plcConfig instanceof Map) {
+            return (Map<String, Object>) plcConfig;
+        }
+        if (plcConfig instanceof String) {
+            try {
+                return objectMapper.readValue((String) plcConfig, MAP_TYPE);
+            } catch (Exception e) {
+                log.warn("瑙f瀽extraParams.plcConfig澶辫触, deviceId={}", device.getId(), e);
+            }
+        }
+        return Collections.emptyMap();
+    }
+    
+    private int parseInteger(Object value) {
+        if (value instanceof Number) {
+            return ((Number) value).intValue();
+        }
+        try {
+            return Integer.parseInt(String.valueOf(value));
+        } catch (NumberFormatException ex) {
+            log.warn("鏃犳硶瑙f瀽鏁存暟鍊�: {}", value);
+            return 0;
+        }
+    }
+    
+    @Override
+    public Map<String, Object> readPlcData(DeviceConfig device, List<String> fieldNames, EnhancedS7Serializer s7Serializer) {
+        if (device == null) {
+            throw new IllegalArgumentException("璁惧閰嶇疆涓嶈兘涓虹┖");
+        }
+        
+        String addressMapping = extractAddressMapping(device);
+        if (addressMapping == null || addressMapping.isEmpty()) {
+            throw new IllegalArgumentException("璁惧閰嶇疆涓璦ddressMapping涓嶈兘涓虹┖");
+        }
+        
         try {
             // 瑙f瀽addressMapping JSON閰嶇疆
-            JSONObject addressMapping = JSONObject.parseObject(config.getAddressMapping());
+            JSONObject addressMappingObj = JSONObject.parseObject(addressMapping);
             
             // 鏋勫缓S7Parameter鍒楄〃
-            List<S7Parameter> parameters = buildS7Parameters(config, addressMapping, fieldNames);
+            String dbArea = extractDbArea(device);
+            List<S7Parameter> parameters = buildS7ParametersForDevice(device, dbArea, addressMappingObj, fieldNames);
             
             // 浠嶱LC璇诲彇鏁版嵁
             List<S7Parameter> results = s7Serializer.read(parameters);
@@ -59,104 +193,209 @@
             
             return resultMap;
         } catch (Exception e) {
-            log.error("璇诲彇PLC鏁版嵁澶辫触锛岃妫�鏌ワ細1.PLC IP鍦板潃鏄惁姝g‘[{}] 2.PLC璁惧鏄惁鍦ㄧ嚎 3.缃戠粶杩炴帴鏄惁姝e父锛宮odule: {}, 璇︾粏閿欒: {}", 
-                config.getPlcIp(), config.getModule(), e.getMessage(), e);
+            log.error("璇诲彇PLC鏁版嵁澶辫触锛岃妫�鏌ワ細1.PLC IP鍦板潃鏄惁姝g‘[{}] 2.PLC璁惧鏄惁鍦ㄧ嚎 3.缃戠粶杩炴帴鏄惁姝e父锛宒eviceId: {}, 璇︾粏閿欒: {}", 
+                device.getPlcIp(), device.getId(), e.getMessage(), e);
             return new HashMap<>();
         }
     }
-
-    /**
-     * 鏍规嵁PlcAddress閰嶇疆鍜屾暟鎹甅ap鍐欏叆PLC
-     * 
-     * @param config PLC鍦板潃鏄犲皠閰嶇疆
-     * @param dataMap 瀛楁鍚�->鍊� 鐨凪ap
-     * @param s7Serializer S7搴忓垪鍖栧櫒
-     */
+    
     @Override
-    public void writePlcData(PlcAddress config, Map<String, Object> dataMap, EnhancedS7Serializer s7Serializer) {
-        if (config == null || config.getAddressMapping() == null) {
-            throw new IllegalArgumentException("PlcAddress閰嶇疆鎴朼ddressMapping涓嶈兘涓虹┖");
+    public void writePlcData(DeviceConfig device, Map<String, Object> dataMap, EnhancedS7Serializer s7Serializer) {
+        if (device == null) {
+            throw new IllegalArgumentException("璁惧閰嶇疆涓嶈兘涓虹┖");
         }
-
+        
+        if (s7Serializer == null) {
+            log.error("S7Serializer涓虹┖锛屾棤娉曞啓鍏LC鏁版嵁: deviceId={}", device.getId());
+            return;
+        }
+        
         try {
+            String addressMapping = extractAddressMapping(device);
+            if (addressMapping == null || addressMapping.isEmpty()) {
+                log.error("璁惧閰嶇疆涓璦ddressMapping涓虹┖: deviceId={}", device.getId());
+                return;
+            }
+            
             // 瑙f瀽addressMapping JSON閰嶇疆
-            JSONObject addressMapping = JSONObject.parseObject(config.getAddressMapping());
+            JSONObject addressMappingObj = JSONObject.parseObject(addressMapping);
             
             // 鏋勫缓S7Parameter鍒楄〃锛屽苟濉厖鍊�
-            List<S7Parameter> parameters = buildS7ParametersWithValues(config, addressMapping, dataMap);
+            String dbArea = extractDbArea(device);
+            List<S7Parameter> parameters = buildS7ParametersWithValuesForDevice(device, dbArea, addressMappingObj, dataMap);
             
             // 鍐欏叆PLC
             s7Serializer.write(parameters);
         } catch (Exception e) {
-            log.error("鍐欏叆PLC鏁版嵁澶辫触锛岃妫�鏌ワ細1.PLC IP鍦板潃鏄惁姝g‘[{}] 2.PLC璁惧鏄惁鍦ㄧ嚎 3.缃戠粶杩炴帴鏄惁姝e父锛宮odule: {}, 璇︾粏閿欒: {}", 
-                config.getPlcIp(), config.getModule(), e.getMessage(), e);
+            log.error("鍐欏叆PLC鏁版嵁澶辫触锛岃妫�鏌ワ細1.PLC IP鍦板潃鏄惁姝g‘[{}] 2.PLC璁惧鏄惁鍦ㄧ嚎 3.缃戠粶杩炴帴鏄惁姝e父锛宒eviceId: {}, 璇︾粏閿欒: {}", 
+                device.getPlcIp(), device.getId(), e.getMessage(), e);
         }
     }
-
-    /**
-     * 璇诲彇PLC鎵�鏈夊瓧娈�
-     * 
-     * @param config PLC鍦板潃鏄犲皠閰嶇疆
-     * @param s7Serializer S7搴忓垪鍖栧櫒
-     * @return 鎵�鏈夊瓧娈电殑鍊�
-     */
+    
     @Override
-    public Map<String, Object> readAllPlcData(PlcAddress config, EnhancedS7Serializer s7Serializer) {
-        if (config == null || config.getAddressMapping() == null) {
-            throw new IllegalArgumentException("PlcAddress閰嶇疆鎴朼ddressMapping涓嶈兘涓虹┖");
+    public Map<String, Object> readAllPlcData(DeviceConfig device, EnhancedS7Serializer s7Serializer) {
+        if (device == null) {
+            throw new IllegalArgumentException("璁惧閰嶇疆涓嶈兘涓虹┖");
         }
-
-        // 鑾峰彇鎵�鏈夊瓧娈靛悕
-        JSONObject addressMapping = JSONObject.parseObject(config.getAddressMapping());
-        List<String> allFields = new ArrayList<>(addressMapping.keySet());
         
-        // 璇诲彇鎵�鏈夊瓧娈�
-        return readPlcData(config, allFields, s7Serializer);
+        if (s7Serializer == null) {
+            log.error("S7Serializer涓虹┖锛屾棤娉曡鍙朠LC鏁版嵁: deviceId={}", device.getId());
+            return new HashMap<>();
+        }
+        
+        try {
+            String addressMapping = extractAddressMapping(device);
+            if (addressMapping == null || addressMapping.isEmpty()) {
+                log.error("璁惧閰嶇疆涓璦ddressMapping涓虹┖: deviceId={}", device.getId());
+                return new HashMap<>();
+            }
+            
+            // 鑾峰彇鎵�鏈夊瓧娈靛悕
+            JSONObject addressMappingObj = JSONObject.parseObject(addressMapping);
+            List<String> allFields = new ArrayList<>(addressMappingObj.keySet());
+            
+            // 璇诲彇鎵�鏈夊瓧娈�
+            return readPlcData(device, allFields, s7Serializer);
+        } catch (Exception e) {
+            log.error("璇诲彇鎵�鏈塒LC鏁版嵁澶辫触: deviceId={}", device.getId(), e);
+            return new HashMap<>();
+        }
     }
-
-    /**
-     * 璇诲彇鍗曚釜瀛楁
-     * 
-     * @param config PLC鍦板潃鏄犲皠閰嶇疆
-     * @param fieldName 瀛楁鍚�
-     * @param s7Serializer S7搴忓垪鍖栧櫒
-     * @return 瀛楁鍊�
-     */
+    
     @Override
-    public Object readPlcField(PlcAddress config, String fieldName, EnhancedS7Serializer s7Serializer) {
+    public Object readPlcField(DeviceConfig device, String fieldName, EnhancedS7Serializer s7Serializer) {
         List<String> fields = new ArrayList<>();
         fields.add(fieldName);
         
-        Map<String, Object> result = readPlcData(config, fields, s7Serializer);
+        Map<String, Object> result = readPlcData(device, fields, s7Serializer);
         return result.get(fieldName);
     }
-
-    /**
-     * 鍐欏叆鍗曚釜瀛楁
-     * 
-     * @param config PLC鍦板潃鏄犲皠閰嶇疆
-     * @param fieldName 瀛楁鍚�
-     * @param value 瀛楁鍊�
-     * @param s7Serializer S7搴忓垪鍖栧櫒
-     */
+    
     @Override
-    public void writePlcField(PlcAddress config, String fieldName, Object value, EnhancedS7Serializer s7Serializer) {
+    public void writePlcField(DeviceConfig device, String fieldName, Object value, EnhancedS7Serializer s7Serializer) {
         Map<String, Object> dataMap = new HashMap<>();
         dataMap.put(fieldName, value);
         
-        writePlcData(config, dataMap, s7Serializer);
+        writePlcData(device, dataMap, s7Serializer);
     }
-
+    
+    @Override
+    public <T> void writePlcDataByEntity(DeviceConfig device, T entity, EnhancedS7Serializer s7Serializer) {
+        if (device == null || entity == null) {
+            throw new IllegalArgumentException("璁惧閰嶇疆鍜屽疄浣撳璞′笉鑳戒负绌�");
+        }
+        
+        try {
+            // 1. 浠巆onfigJson涓幏鍙栧湴鍧�鏄犲皠锛堝瓧娈靛悕 -> 鍋忕Щ閲忥級
+            Map<String, Object> addressMapping = ConfigJsonHelper.parseToMap(device.getConfigJson(), objectMapper);
+            if (addressMapping.isEmpty()) {
+                throw new IllegalArgumentException("璁惧閰嶇疆涓湭鎵惧埌鍦板潃鏄犲皠閰嶇疆, deviceId=" + device.getId());
+            }
+            
+            // 2. 鑾峰彇dbArea鍜宐eginIndex
+            String dbArea = extractDbArea(device);
+            int beginIndex = extractBeginIndex(device);
+            
+            // 3. 鑾峰彇瀛楁閰嶇疆锛堢被鍨嬪拰count锛�
+            Map<String, FieldConfig> fieldConfigMap = extractFieldConfigMap(device);
+            
+            // 4. 瑙f瀽瀹炰綋绫伙紝鑾峰彇鎵�鏈夊甫@S7Variable娉ㄨВ鐨勫瓧娈�
+            Class<?> entityClass = entity.getClass();
+            List<S7Parameter> parameters = new ArrayList<>();
+            
+            for (Field field : entityClass.getDeclaredFields()) {
+                S7Variable annotation = field.getAnnotation(S7Variable.class);
+                if (annotation == null) {
+                    continue;
+                }
+                
+                // 鑾峰彇瀛楁鍚嶏紙浠庢敞瑙g殑address鑾峰彇锛屽搴攃onfigJson涓殑paramKey锛�
+                String fieldName = annotation.address();
+                if (fieldName == null || fieldName.isEmpty()) {
+                    continue;
+                }
+                
+                // 浠巃ddressMapping涓幏鍙栧亸绉婚噺
+                Object offsetObj = addressMapping.get(fieldName);
+                if (offsetObj == null) {
+                    log.warn("瀛楁 {} 鍦╟onfigJson鍦板潃鏄犲皠涓笉瀛樺湪锛岃烦杩�", fieldName);
+                    continue;
+                }
+                
+                int offset;
+                if (offsetObj instanceof Number) {
+                    offset = ((Number) offsetObj).intValue();
+                } else {
+                    offset = Integer.parseInt(String.valueOf(offsetObj));
+                }
+                
+                // 鏋勫缓瀹屾暣鍦板潃锛歞bArea + (beginIndex + offset)
+                String fullAddress = dbArea + "." + (beginIndex + offset);
+                
+                // 纭畾鏁版嵁绫诲瀷鍜宑ount
+                // 浼樺厛绾э細1. 娉ㄨВ涓殑type鍜宑ount 2. configJson涓殑閰嶇疆 3. 鏍规嵁瀛楁鍚嶆帹鏂�
+                EDataType dataType = annotation.type();
+                int count = annotation.count();
+                
+                // 濡傛灉娉ㄨВ涓病鏈夋寚瀹歝ount锛屽皾璇曚粠configJson鎴栧瓧娈靛悕鎺ㄦ柇
+                if (count <= 0) {
+                    FieldConfig fieldConfig = fieldConfigMap.get(fieldName);
+                    if (fieldConfig != null && fieldConfig.count > 0) {
+                        count = fieldConfig.count;
+                    } else {
+                        count = determineFieldCountByName(fieldName);
+                    }
+                }
+                
+                // 濡傛灉娉ㄨВ涓殑绫诲瀷鏄疷INT16浣嗗瓧娈垫槸String绫诲瀷锛屽皾璇曚粠configJson鑾峰彇
+                if (dataType == EDataType.UINT16 && field.getType() == String.class) {
+                    FieldConfig fieldConfig = fieldConfigMap.get(fieldName);
+                    if (fieldConfig != null && fieldConfig.dataType != null) {
+                        dataType = fieldConfig.dataType;
+                    } else {
+                        dataType = determineFieldTypeByName(fieldName);
+                    }
+                }
+                
+                // 鑾峰彇瀛楁鍊�
+                field.setAccessible(true);
+                Object value = field.get(entity);
+                if (value == null) {
+                    continue; // 璺宠繃null鍊�
+                }
+                
+                // 鍒涘缓S7Parameter骞惰缃��
+                S7Parameter parameter = new S7Parameter(fullAddress, dataType, count);
+                parameter.setValue(value);
+                parameters.add(parameter);
+            }
+            
+            if (parameters.isEmpty()) {
+                log.warn("瀹炰綋绫� {} 涓病鏈夋壘鍒版湁鏁堢殑瀛楁锛屾棤娉曞啓鍏LC", entityClass.getSimpleName());
+                return;
+            }
+            
+            // 5. 鍐欏叆PLC
+            s7Serializer.write(parameters);
+            
+            log.info("鏍规嵁瀹炰綋绫诲啓鍏LC鏁版嵁鎴愬姛: deviceId={}, entityClass={}, fields={}", 
+                    device.getId(), entityClass.getSimpleName(), parameters.size());
+            
+        } catch (Exception e) {
+            log.error("鏍规嵁瀹炰綋绫诲啓鍏LC鏁版嵁澶辫触: deviceId={}, entityClass={}", 
+                    device.getId(), entity != null ? entity.getClass().getSimpleName() : "null", e);
+            throw new RuntimeException("鍐欏叆PLC鏁版嵁澶辫触: " + e.getMessage(), e);
+        }
+    }
+    
     /**
-     * 鏋勫缓S7Parameter鍒楄〃锛堜笉鍖呭惈鍊硷級
-     * 
-     * @param config PLC鍦板潃閰嶇疆
-     * @param addressMapping 鍦板潃鏄犲皠
-     * @param fieldNames 瀛楁鍚嶅垪琛�
-     * @return S7Parameter鍒楄〃
+     * 鏋勫缓S7Parameter鍒楄〃锛堜笉鍖呭惈鍊硷級- 鍩轰簬DeviceConfig
      */
-    private List<S7Parameter> buildS7Parameters(PlcAddress config, JSONObject addressMapping, List<String> fieldNames) {
+    private List<S7Parameter> buildS7ParametersForDevice(DeviceConfig device, String dbArea, JSONObject addressMapping, List<String> fieldNames) {
         List<S7Parameter> parameters = new ArrayList<>();
+        
+        // 鑾峰彇瀛楁閰嶇疆锛堜粠configJson涓В鏋愮被鍨嬪拰count锛�
+        Map<String, FieldConfig> fieldConfigMap = extractFieldConfigMap(device);
         
         for (String fieldName : fieldNames) {
             if (!addressMapping.containsKey(fieldName)) {
@@ -164,30 +403,39 @@
                 continue;
             }
             
-            // 鑾峰彇瀛楁鐨勫亸绉诲湴鍧�
-            int offset = addressMapping.getInteger(fieldName);
+            // 鑾峰彇瀛楁鐨勫亸绉诲湴鍧�锛坅ddressMapping涓彧瀛樺偍鏁板瓧鍋忕Щ閲忥級
+            Object offsetObj = addressMapping.get(fieldName);
+            int offset;
+            if (offsetObj instanceof Number) {
+                offset = ((Number) offsetObj).intValue();
+            } else {
+                offset = Integer.parseInt(String.valueOf(offsetObj));
+            }
             
             // 鏋勫缓瀹屾暣鍦板潃锛歞bArea + offset锛堝锛欴B12.2锛�
-            String fullAddress = config.getDbArea() + "." + offset;
+            String fullAddress = dbArea + "." + offset;
             
-            // 鍒涘缓S7Parameter锛岄粯璁や娇鐢║INT16绫诲瀷锛�16浣嶆棤绗﹀彿鏁存暟锛�
-            S7Parameter parameter = new S7Parameter(fullAddress, EDataType.UINT16, 1);
+            // 鑾峰彇瀛楁绫诲瀷鍜岄暱搴︼紙浠巆onfigJson鎴栨牴鎹瓧娈靛悕鎺ㄦ柇锛�
+            FieldConfig fieldConfig = fieldConfigMap.getOrDefault(fieldName, new FieldConfig());
+            EDataType dataType = fieldConfig.dataType != null ? fieldConfig.dataType : determineFieldTypeByName(fieldName);
+            int count = fieldConfig.count > 0 ? fieldConfig.count : determineFieldCountByName(fieldName);
+            
+            // 鍒涘缓S7Parameter
+            S7Parameter parameter = new S7Parameter(fullAddress, dataType, count);
             parameters.add(parameter);
         }
         
         return parameters;
     }
-
+    
     /**
-     * 鏋勫缓S7Parameter鍒楄〃锛堝寘鍚�硷級
-     * 
-     * @param config PLC鍦板潃閰嶇疆
-     * @param addressMapping 鍦板潃鏄犲皠
-     * @param dataMap 瀛楁鍚�->鍊� 鐨凪ap
-     * @return S7Parameter鍒楄〃
+     * 鏋勫缓S7Parameter鍒楄〃锛堝寘鍚�硷級- 鍩轰簬DeviceConfig
      */
-    private List<S7Parameter> buildS7ParametersWithValues(PlcAddress config, JSONObject addressMapping, Map<String, Object> dataMap) {
+    private List<S7Parameter> buildS7ParametersWithValuesForDevice(DeviceConfig device, String dbArea, JSONObject addressMapping, Map<String, Object> dataMap) {
         List<S7Parameter> parameters = new ArrayList<>();
+        
+        // 鑾峰彇瀛楁閰嶇疆锛堜粠configJson涓В鏋愮被鍨嬪拰count锛�
+        Map<String, FieldConfig> fieldConfigMap = extractFieldConfigMap(device);
         
         for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
             String fieldName = entry.getKey();
@@ -198,18 +446,154 @@
                 continue;
             }
             
-            // 鑾峰彇瀛楁鐨勫亸绉诲湴鍧�
-            int offset = addressMapping.getInteger(fieldName);
+            // 鑾峰彇瀛楁鐨勫亸绉诲湴鍧�锛坅ddressMapping涓彧瀛樺偍鏁板瓧鍋忕Щ閲忥級
+            Object offsetObj = addressMapping.get(fieldName);
+            int offset;
+            if (offsetObj instanceof Number) {
+                offset = ((Number) offsetObj).intValue();
+            } else {
+                offset = Integer.parseInt(String.valueOf(offsetObj));
+            }
             
             // 鏋勫缓瀹屾暣鍦板潃
-            String fullAddress = config.getDbArea() + "." + offset;
+            String fullAddress = dbArea + "." + offset;
+            
+            // 鑾峰彇瀛楁绫诲瀷鍜岄暱搴︼紙浠巆onfigJson鎴栨牴鎹瓧娈靛悕鎺ㄦ柇锛�
+            FieldConfig fieldConfig = fieldConfigMap.getOrDefault(fieldName, new FieldConfig());
+            EDataType dataType = fieldConfig.dataType != null ? fieldConfig.dataType : determineFieldTypeByName(fieldName);
+            int count = fieldConfig.count > 0 ? fieldConfig.count : determineFieldCountByName(fieldName);
             
             // 鍒涘缓S7Parameter锛岃缃��
-            S7Parameter parameter = new S7Parameter(fullAddress, EDataType.UINT16, 1);
+            S7Parameter parameter = new S7Parameter(fullAddress, dataType, count);
             parameter.setValue(value);
             parameters.add(parameter);
         }
         
         return parameters;
     }
+    
+    /**
+     * 瀛楁閰嶇疆淇℃伅
+     */
+    private static class FieldConfig {
+        EDataType dataType;
+        int count;
+        
+        FieldConfig() {
+            this.dataType = null;
+            this.count = 0;
+        }
+        
+        FieldConfig(EDataType dataType, int count) {
+            this.dataType = dataType;
+            this.count = count;
+        }
+    }
+    
+    /**
+     * 浠庤澶囬厤缃腑鎻愬彇瀛楁閰嶇疆鏄犲皠锛堢被鍨嬪拰count锛�
+     * configJson鏍煎紡: [{paramKey: "plcGlassId1", paramValue: "4", description: "鐜荤拑id1", dataType: "STRING", count: 20}]
+     */
+    private Map<String, FieldConfig> extractFieldConfigMap(DeviceConfig device) {
+        Map<String, FieldConfig> configMap = new HashMap<>();
+        
+        try {
+            String configJson = device.getConfigJson();
+            if (configJson == null || configJson.trim().isEmpty()) {
+                return configMap;
+            }
+            
+            String trimmed = configJson.trim();
+            // 濡傛灉configJson鏄暟缁勬牸寮忥紝瑙f瀽鏁扮粍
+            if (trimmed.startsWith("[")) {
+                List<Map<String, Object>> paramList = objectMapper.readValue(trimmed, 
+                    new TypeReference<List<Map<String, Object>>>() {});
+                
+                for (Map<String, Object> param : paramList) {
+                    Object paramKeyObj = param.get("paramKey");
+                    if (paramKeyObj == null) {
+                        continue;
+                    }
+                    String paramKey = String.valueOf(paramKeyObj);
+                    
+                    EDataType dataType = null;
+                    int count = 0;
+                    
+                    // 瑙f瀽dataType
+                    Object dataTypeObj = param.get("dataType");
+                    if (dataTypeObj != null) {
+                        String dataTypeStr = String.valueOf(dataTypeObj).toUpperCase();
+                        try {
+                            dataType = EDataType.valueOf(dataTypeStr);
+                        } catch (IllegalArgumentException e) {
+                            log.debug("鏃犳硶瑙f瀽鏁版嵁绫诲瀷: {}, 瀛楁: {}", dataTypeStr, paramKey);
+                        }
+                    }
+                    
+                    // 瑙f瀽count
+                    Object countObj = param.get("count");
+                    if (countObj != null) {
+                        if (countObj instanceof Number) {
+                            count = ((Number) countObj).intValue();
+                        } else {
+                            try {
+                                count = Integer.parseInt(String.valueOf(countObj));
+                            } catch (NumberFormatException e) {
+                                log.debug("鏃犳硶瑙f瀽count鍊�: {}, 瀛楁: {}", countObj, paramKey);
+                            }
+                        }
+                    }
+                    
+                    if (dataType != null || count > 0) {
+                        configMap.put(paramKey, new FieldConfig(dataType, count));
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.debug("瑙f瀽瀛楁閰嶇疆鏄犲皠澶辫触: {}", e.getMessage());
+        }
+        
+        return configMap;
+    }
+    
+    /**
+     * 鏍规嵁瀛楁鍚嶆帹鏂暟鎹被鍨�
+     */
+    private EDataType determineFieldTypeByName(String fieldName) {
+        if (fieldName == null) {
+            return EDataType.UINT16;
+        }
+        
+        String lowerName = fieldName.toLowerCase();
+        // 鐜荤拑ID瀛楁閫氬父鏄瓧绗︿覆
+        if (lowerName.contains("glassid") || lowerName.contains("glass_id") || 
+            lowerName.startsWith("plcglassid")) {
+            return EDataType.STRING;
+        }
+        // 鑱旀満鐘舵�佺瓑甯冨皵鏍囪
+        if (lowerName.contains("online")) {
+            return EDataType.BOOL;
+        }
+        // 榛樿杩斿洖UINT16
+        return EDataType.UINT16;
+    }
+    
+    /**
+     * 鏍规嵁瀛楁鍚嶆帹鏂瓧娈甸暱搴�/鏁伴噺
+     */
+    private int determineFieldCountByName(String fieldName) {
+        if (fieldName == null) {
+            return 1;
+        }
+        
+        String lowerName = fieldName.toLowerCase();
+        // 鐜荤拑ID閫氬父鏄�20涓瓧绗�
+        if (lowerName.contains("glassid") || lowerName.contains("glass_id") || 
+            lowerName.startsWith("plcglassid")) {
+            return 20; // 榛樿20涓瓧绗�
+        }
+        
+        // 榛樿杩斿洖1
+        return 1;
+    }
 }

--
Gitblit v1.8.0