learshaw 4 месяцев назад
Родитель
Сommit
bb36c25a44

+ 10 - 20
ems/ems-cloud/ems-dev-adapter/src/main/java/com/ruoyi/ems/core/MqttTemplate.java

@@ -1,5 +1,5 @@
 /*
- * 文 件 名:  MqttClient
+ * 文 件 名:  MqttTemplate
  * 版    权:  浩鲸云计算科技股份有限公司
  * 描    述:  <描述>
  * 修 改 人:  lvwenbin
@@ -122,9 +122,16 @@ public class MqttTemplate {
         }
     }
 
-    public void sendHex(String topic, String hexPayload, int qos, boolean retained) {
+    /**
+     * 发送十六进制数据 - 优化版本,直接接收字节数组
+     *
+     * @param topic       主题
+     * @param payloadBytes 十六进制字节数组
+     * @param qos         消息级别
+     * @param retained    回复
+     */
+    public void sendHex(String topic, byte[] payloadBytes, int qos, boolean retained) {
         try {
-            byte[] payloadBytes = hexStringToByteArray(hexPayload);
             MqttMessage message = new MqttMessage();
             message.setPayload(payloadBytes);
             message.setQos(qos);
@@ -135,21 +142,4 @@ public class MqttTemplate {
             log.error("[SendHex]fail!", e);
         }
     }
-
-    private byte[] hexStringToByteArray(String hexString) {
-        // 去除字符串前后的空格
-        hexString = hexString.trim();
-
-        // 分割字符串
-        String[] hexParts = hexString.split(" ");
-        byte[] byteArray = new byte[hexParts.length];
-
-        for (int i = 0; i < hexParts.length; i++) {
-            // 将每个十六进制部分转换为整数,再转为字节
-            int value = Integer.parseInt(hexParts[i], 16);
-            byteArray[i] = (byte) value;
-        }
-
-        return byteArray;
-    }
 }

+ 25 - 23
ems/ems-cloud/ems-dev-adapter/src/main/java/com/ruoyi/ems/handle/Keka86BsHandler.java

@@ -1,5 +1,5 @@
 /*
- * 文 件 名:  KekaBs86Handler
+ * 文 件 名:  Keka86BsHandler
  * 版    权:  华设设计集团股份有限公司
  * 描    述:  <描述>
  * 修 改 人:  lvwenbin
@@ -18,6 +18,7 @@ import com.ruoyi.ems.domain.EmsObjAttrValue;
 import com.ruoyi.ems.enums.DevOnlineStatus;
 import com.ruoyi.ems.model.AbilityPayload;
 import com.ruoyi.ems.model.CallResponse;
+import com.ruoyi.ems.model.ModbusCommand;
 import com.ruoyi.ems.model.QueryDevice;
 import com.ruoyi.ems.model.keka.DeviceStatus;
 import org.apache.commons.collections4.CollectionUtils;
@@ -90,20 +91,20 @@ public class Keka86BsHandler extends BaseDevHandler {
         String buttonId = attrMap.get("buttonId");
 
         if (StringUtils.equals("on-off", abilityParam.getAbilityKey())) {
-            String payload = buildControlCommand(Integer.parseInt(buttonId),
+            ModbusCommand command = buildControlCommand(Integer.parseInt(buttonId),
                 Integer.parseInt(abilityParam.getAbilityParam()));
             // 发送消息到MQTT服务器
             String topic = TOPIC_PREFIX + gatewayId;
-            sendMqttHex(topic, payload, 2, false);
-            saveCallLog(abilityParam, payload, System.currentTimeMillis(), 0);
+            sendMqttHex(topic, command);
+            saveCallLog(abilityParam, command.getCommandHex(), System.currentTimeMillis(), 0);
             callResponse = new CallResponse<>(0, "执行成功!");
         }
         else if (StringUtils.equals("syncState", abilityParam.getAbilityKey())) {
-            String payload = buildReadCommand(Integer.parseInt(buttonId));
+            ModbusCommand command = buildReadCommand(Integer.parseInt(buttonId));
             // 发送消息到MQTT服务器
             String topic = TOPIC_PREFIX + gatewayId;
-            sendMqttHex(topic, payload, 2, false);
-            saveCallLog(abilityParam, payload, System.currentTimeMillis(), 0);
+            sendMqttHex(topic, command);
+            saveCallLog(abilityParam, command.getCommandHex(), System.currentTimeMillis(), 0);
             callResponse = new CallResponse<>(0, "执行成功!");
         }
         else {
@@ -181,13 +182,13 @@ public class Keka86BsHandler extends BaseDevHandler {
     }
 
     /**
-     * 生成控制指令 (开/关)
+     * 生成控制指令 (开/关) - 优化版本
      *
      * @param lightId 灯ID (1, 2, 3)
      * @param state   状态 (1=开, 0=关)
-     * @return 十六进制字符串 (如: "01 06 10 21 00 01 1C C0")
+     * @return ModbusCommand 包含字节数组和十六进制字符串
      */
-    public String buildControlCommand(int lightId, int state) {
+    public ModbusCommand buildControlCommand(int lightId, int state) {
         if (lightId < 1 || lightId > 3) {
             throw new IllegalArgumentException("灯ID必须是1-3");
         }
@@ -217,16 +218,17 @@ public class Keka86BsHandler extends BaseDevHandler {
         fullFrame[6] = (byte) (crc & 0xFF);              // CRC低字节在前
         fullFrame[7] = (byte) (crc >> 8);                // CRC高字节在后
 
-        return bytesToHexString(fullFrame);
+        String hexString = bytesToHexString(fullFrame);
+        return new ModbusCommand(fullFrame, hexString);
     }
 
     /**
-     * 生成读取指令
+     * 生成读取指令 - 优化版本
      *
      * @param lightId 灯ID (1, 2, 3)
-     * @return 十六进制字符串 (如: "01 03 10 21 00 02 90 C1")
+     * @return ModbusCommand 包含字节数组和十六进制字符串
      */
-    public String buildReadCommand(int lightId) {
+    public ModbusCommand buildReadCommand(int lightId) {
         if (lightId < 1 || lightId > 3) {
             throw new IllegalArgumentException("灯ID必须是1-3");
         }
@@ -250,7 +252,8 @@ public class Keka86BsHandler extends BaseDevHandler {
         fullFrame[6] = (byte) (crc & 0xFF);              // CRC低字节
         fullFrame[7] = (byte) (crc >> 8);                // CRC高字节
 
-        return bytesToHexString(fullFrame);
+        String hexString = bytesToHexString(fullFrame);
+        return new ModbusCommand(fullFrame, hexString);
     }
 
     /**
@@ -379,16 +382,15 @@ public class Keka86BsHandler extends BaseDevHandler {
     }
 
     /**
-     * 发送MQTT消息
+     * 发送MQTT消息 - 优化版本
      *
-     * @param topic    主题
-     * @param payload  负载数据
-     * @param qos      质量服务等级
-     * @param retained 是否保留消息
+     * @param topic   主题
+     * @param command Modbus指令对象 (包含字节数组和十六进制字符串)
      */
-    public void sendMqttHex(String topic, String payload, int qos, boolean retained) {
-        log.info("[Send] Topic:{}, message:{}, qos:{}, retained:{}", topic, payload, qos, retained);
-        mqttTemplate.sendHex(topic, payload, 2, false);
+    public void sendMqttHex(String topic, ModbusCommand command) {
+        log.info("[Send] Topic:{}, message:{}, qos:{}, retained:{}",
+            topic, command.getCommandHex(), 2, false);
+        mqttTemplate.sendHex(topic, command.getCommandBytes(), 2, false);
     }
 
     /**

+ 38 - 0
ems/ems-cloud/ems-dev-adapter/src/main/java/com/ruoyi/ems/model/ModbusCommand.java

@@ -0,0 +1,38 @@
+/*
+ * 文 件 名:  ModbusCommand
+ * 版    权:  华设设计集团股份有限公司
+ * 描    述:  <描述>
+ * 修 改 人:  lvwenbin
+ * 修改时间:  2025/12/5
+ * 跟踪单号:  <跟踪单号>
+ * 修改单号:  <修改单号>
+ * 修改内容:  <修改内容>
+ */
+package com.ruoyi.ems.model;
+
+/**
+ * <一句话功能简述>
+ * <功能详细描述>
+ *
+ * @author lvwenbin
+ * @version [版本号, 2025/12/5]
+ * @see [相关类/方法]
+ * @since [产品/模块版本]
+ */
+public class ModbusCommand {
+    private final byte[] commandBytes;
+    private final String commandHex;
+
+    public ModbusCommand(byte[] commandBytes, String commandHex) {
+        this.commandBytes = commandBytes;
+        this.commandHex = commandHex;
+    }
+
+    public byte[] getCommandBytes() {
+        return commandBytes;
+    }
+
+    public String getCommandHex() {
+        return commandHex;
+    }
+}

+ 66 - 67
ems/ems-cloud/ems-dev-adapter/src/main/resources/application-local.yml

@@ -106,15 +106,15 @@ adapter:
         wCv: 'C_2010_AI_0005'
         xfCv: 'C_2010_AI_0006'
         pfCv: 'C_2010_AI_0007'
-        lwDpAlarm: 'C_2010_BI_0008'
-        fjUvAlarm: 'C_2010_BI_0009'
-        afAlarm: 'C_2010_BI_0010'
-        xfStatus: 'C_2010_BI_0011'
-        xfMA: 'C_2010_BI_0012'
-        xfFault: 'C_2010_BI_0013'
-        pfStatus: 'C_2010_BI_0014'
-        pfMA: 'C_2010_BI_0015'
-        pfFault: 'C_2010_BI_0016'
+        lwDpAlarm: 'C_2010_DI_0008'
+        fjUvAlarm: 'C_2010_DI_0009'
+        afAlarm: 'C_2010_DI_0010'
+        xfStatus: 'C_2010_DI_0011'
+        xfMA: 'C_2010_DI_0012'
+        xfFault: 'C_2010_DI_0013'
+        pfStatus: 'C_2010_DI_0014'
+        pfMA: 'C_2010_DI_0015'
+        pfFault: 'C_2010_DI_0016'
         timeStatus: 'C_2010_AV_0000,C_2010_AV_0001,C_2010_AV_0002,C_2010_AV_0003'
         xfTempSetVal: 'C_2010_AV_0004'
         LnSu: 'C_2010_BV_0009'
@@ -146,9 +146,9 @@ adapter:
         wCv: 'C_2012_AI_0005'
         xfCv: 'C_2012_AI_0006'
         pfCv: 'C_2012_AI_0007'
-        lwDpAlarm: 'C_2012_BI_0008'
-        fjUvAlarm: 'C_2012_BI_0009'
-        afAlarm: 'C_2012_BI_0010'
+        lwDpAlarm: 'C_2012_DI_0008'
+        fjUvAlarm: 'C_2012_DI_0009'
+        afAlarm: 'C_2012_DI_0010'
         timeStatus: 'C_2012_AV_0000,C_2012_AV_0001,C_2012_AV_0002,C_2012_AV_0003'
         xfTempSetVal: 'C_2012_AV_0004'
         LnSu: 'C_2012_BV_0009'
@@ -164,9 +164,9 @@ adapter:
         wCv: 'C_1009_AI_0005'
         xfCv: 'C_1009_AI_0006'
         pfCv: 'C_1009_AI_0007'
-        lwDpAlarm: 'C_1009_BI_0008'
-        fjUvAlarm: 'C_1009_BI_0009'
-        afAlarm: 'C_1009_BI_0010'
+        lwDpAlarm: 'C_1009_DI_0008'
+        fjUvAlarm: 'C_1009_DI_0009'
+        afAlarm: 'C_1009_DI_0010'
         xfStatus: 'C_1201_DI_0012'
         xfMA: 'C_1201_DI_0014'
         xfFault: 'C_1201_DI_0013'
@@ -185,12 +185,12 @@ adapter:
         wCv: 'C_1010_AI_0005'
         xfCv: 'C_1009_AI_0006'
         pfCv: 'C_1010_AI_0007'
-        lwDpAlarm: 'C_1010_BI_0008'
-        fjUvAlarm: 'C_1010_BI_0009'
-        afAlarm: 'C_1010_BI_0010'
+        lwDpAlarm: 'C_1010_DI_0008'
+        fjUvAlarm: 'C_1010_DI_0009'
+        afAlarm: 'C_1010_DI_0010'
         xfStatus: 'C_1201_DI_0009'
-        xfMA: 'C_1201_DI_0010'
-        xfFault: 'C_1201_DI_0011'
+        xfMA: 'C_1201_DI_0011'
+        xfFault: 'C_1201_DI_0010'
         timeStatus: 'C_1010_AV_0000,C_1010_AV_0001,C_1010_AV_0002,C_1010_AV_0003'
         xfTempSetVal: 'C_1010_AV_0004'
         LnSu: 'C_1010_BV_0009'
@@ -206,9 +206,9 @@ adapter:
         wCv: 'C_1011_AI_0005'
         xfCv: 'C_1011_AI_0006'
         pfCv: 'C_1011_AI_0007'
-        lwDpAlarm: 'C_1011_BI_0008'
-        fjUvAlarm: 'C_1011_BI_0009'
-        afAlarm: 'C_1011_BI_0010'
+        lwDpAlarm: 'C_1011_DI_0008'
+        fjUvAlarm: 'C_1011_DI_0009'
+        afAlarm: 'C_1011_DI_0010'
         xfStatus: 'C_1201_DI_0006'
         xfMA: 'C_1201_DI_0007'
         xfFault: 'C_1201_DI_0008'
@@ -227,15 +227,15 @@ adapter:
         wCv: 'C_1012_AI_0005'
         xfCv: 'C_1012_AI_0006'
         pfCv: 'C_1012_AI_0007'
-        lwDpAlarm: 'C_1012_BI_0008'
-        fjUvAlarm: 'C_1012_BI_0009'
-        afAlarm: 'C_1012_BI_0010'
-        xfStatus: 'C_1012_BI_0011'
-        xfMA: 'C_1012_BI_0012'
-        xfFault: 'C_1012_BI_0013'
-        pfStatus: 'C_1012_BI_0014'
-        pfMA: 'C_1012_BI_0015'
-        pfFault: 'C_1012_BI_0016'
+        lwDpAlarm: 'C_1012_DI_0008'
+        fjUvAlarm: 'C_1012_DI_0009'
+        afAlarm: 'C_1012_DI_0010'
+        xfStatus: 'C_1012_DI_0011'
+        xfMA: 'C_1012_DI_0012'
+        xfFault: 'C_1012_DI_0013'
+        pfStatus: 'C_1012_DI_0014'
+        pfMA: 'C_1012_DI_0015'
+        pfFault: 'C_1012_DI_0016'
         timeStatus: 'C_1012_AV_0000,C_1012_AV_0001,C_1012_AV_0002,C_1012_AV_0003'
         xfTempSetVal: 'C_1012_AV_0004'
         LnSu: 'C_1012_BV_0009'
@@ -265,12 +265,12 @@ adapter:
         hfTemp: 'C_2012_AI_0018'
         xfCv: 'C_2012_AI_0019'
         wCv: 'C_2012_AI_0020'
-        lwDpAlarm: 'C_2012_BI_0037'
-        fjUvAlarm: 'C_2012_BI_0038'
-        afAlarm: 'C_2012_BI_0039'
-        xfStatus: 'C_2012_BI_0040'
-        xfMA: 'C_2012_BI_0041'
-        xfFault: 'C_2012_BI_0042'
+        lwDpAlarm: 'C_2012_DI_0037'
+        fjUvAlarm: 'C_2012_DI_0038'
+        afAlarm: 'C_2012_DI_0039'
+        xfStatus: 'C_2012_DI_0040'
+        xfMA: 'C_2012_DI_0041'
+        xfFault: 'C_2012_DI_0042'
         timeStatus: 'C_2012_AV_0010,C_2012_AV_0011,C_2012_AV_0012,C_2012_AV_0013'
         xfTempSetVal: 'C_2012_AV_0014'
         LnSu: 'C_2012_BV_0019'
@@ -282,12 +282,12 @@ adapter:
         hfTemp: 'C_1011_AI_0018'
         xfCv: 'C_1011_AI_0019'
         wCv: 'C_1011_AI_0020'
-        lwDpAlarm: 'C_1011_BI_0037'
-        fjUvAlarm: 'C_1011_BI_0038'
-        afAlarm: 'C_1011_BI_0039'
-        xfStatus: 'C_1011_BI_0040'
-        xfMA: 'C_1011_BI_0041'
-        xfFault: 'C_1011_BI_0042'
+        lwDpAlarm: 'C_1011_DI_0037'
+        fjUvAlarm: 'C_1011_DI_0038'
+        afAlarm: 'C_1011_DI_0039'
+        xfStatus: 'C_1011_DI_0040'
+        xfMA: 'C_1011_DI_0041'
+        xfFault: 'C_1011_DI_0042'
         timeStatus: 'C_1011_AV_0010,C_1011_AV_0011,C_1011_AV_0012,C_1011_AV_0013'
         xfTempSetVal: 'C_1011_AV_0014'
         LnSu: 'C_1011_BV_0019'
@@ -313,46 +313,45 @@ adapter:
     wtMapper:
       # 北区水箱
       'Z020-B-WT-1':
-        tankLevel: 'C_2008_AI_0000'
-        highLevelAlarm: 'C_2008_BI_0001'
-        lowLevelAlarm: 'C_2008_BI_0002'
+        highLevelAlarm: 'C_2008_DI_0001'
+        lowLevelAlarm: 'C_2008_DI_0002'
       # 南区水箱
       'Z020-N-WT-1':
-        highLevelAlarm: '1008-BI0'
-        lowLevelAlarm: '1008-BI1'
+        highLevelAlarm: 'C_1008_DI_0000'
+        lowLevelAlarm: 'C_1008_DI_0001'
     wpMapper:
       # 北区1号泵
       'Z020-B-WP-1':
-        autoState: 'C_2008_BI_0006'
-        runningState: 'C_2008_BI_0007'
-        faultState: 'C_2008_BI_0008'
+        autoState: 'C_2008_DI_0006'
+        runningState: 'C_2008_DI_0007'
+        faultState: 'C_2008_DI_0008'
       # 北区2号泵
       'Z020-B-WP-2':
-        autoState: 'C_2008_BI_0003'
-        runningState: 'C_2008_BI_0004'
-        faultState: 'C_2008_BI_0005'
+        autoState: 'C_2008_DI_0003'
+        runningState: 'C_2008_DI_0004'
+        faultState: 'C_2008_DI_0005'
       # 北区1号生活泵
       'Z020-B-WP-SH-1':
-        runningState: 'C_2008_BI_0009'
-        faultState: 'C_2008_BI_0010'
+        runningState: 'C_2008_DI_0009'
+        faultState: 'C_2008_DI_0010'
       # 北区2号生活泵
       'Z020-B-WP-SH-2':
-        runningState: 'C_2008_BI_0011'
-        faultState: 'C_2008_BI_0012'
+        runningState: 'C_2008_DI_0011'
+        faultState: 'C_2008_DI_0012'
       # 北区3号生活泵
       'Z020-B-WP-SH-3':
-        runningState: 'C_2008_BI_0013'
-        faultState: 'C_2008_BI_0014'
+        runningState: 'C_2008_DI_0013'
+        faultState: 'C_2008_DI_0014'
       # 南区1号泵
       'Z020-N-WP-1':
-        autoState: '1008-BI2'
-        runningState: '1008-BI3'
-        faultState: '1008-BI4'
+        autoState: 'C_1008_DI_0002'
+        runningState: 'C_1008_DI_0003'
+        faultState: 'C_1008_DI_0004'
       # 南区2号泵
       'Z020-N-WP-2':
-        autoState: '1008-BI5'
-        runningState: '1008-BI6'
-        faultState: '1008-BI7'
+        autoState: 'C_1008_DI_0005'
+        runningState: 'C_1008_DI_0006'
+        faultState: 'C_1008_DI_0007'
     lightMapper:
       'Z020-B-LIGHT-01':
         setCtl-OnOff: 'C_8001_BV_0000'

+ 66 - 67
ems/ems-cloud/ems-dev-adapter/src/main/resources/application-prod-ct.yml

@@ -106,15 +106,15 @@ adapter:
         wCv: 'C_2010_AI_0005'
         xfCv: 'C_2010_AI_0006'
         pfCv: 'C_2010_AI_0007'
-        lwDpAlarm: 'C_2010_BI_0008'
-        fjUvAlarm: 'C_2010_BI_0009'
-        afAlarm: 'C_2010_BI_0010'
-        xfStatus: 'C_2010_BI_0011'
-        xfMA: 'C_2010_BI_0012'
-        xfFault: 'C_2010_BI_0013'
-        pfStatus: 'C_2010_BI_0014'
-        pfMA: 'C_2010_BI_0015'
-        pfFault: 'C_2010_BI_0016'
+        lwDpAlarm: 'C_2010_DI_0008'
+        fjUvAlarm: 'C_2010_DI_0009'
+        afAlarm: 'C_2010_DI_0010'
+        xfStatus: 'C_2010_DI_0011'
+        xfMA: 'C_2010_DI_0012'
+        xfFault: 'C_2010_DI_0013'
+        pfStatus: 'C_2010_DI_0014'
+        pfMA: 'C_2010_DI_0015'
+        pfFault: 'C_2010_DI_0016'
         timeStatus: 'C_2010_AV_0000,C_2010_AV_0001,C_2010_AV_0002,C_2010_AV_0003'
         xfTempSetVal: 'C_2010_AV_0004'
         LnSu: 'C_2010_BV_0009'
@@ -146,9 +146,9 @@ adapter:
         wCv: 'C_2012_AI_0005'
         xfCv: 'C_2012_AI_0006'
         pfCv: 'C_2012_AI_0007'
-        lwDpAlarm: 'C_2012_BI_0008'
-        fjUvAlarm: 'C_2012_BI_0009'
-        afAlarm: 'C_2012_BI_0010'
+        lwDpAlarm: 'C_2012_DI_0008'
+        fjUvAlarm: 'C_2012_DI_0009'
+        afAlarm: 'C_2012_DI_0010'
         timeStatus: 'C_2012_AV_0000,C_2012_AV_0001,C_2012_AV_0002,C_2012_AV_0003'
         xfTempSetVal: 'C_2012_AV_0004'
         LnSu: 'C_2012_BV_0009'
@@ -164,9 +164,9 @@ adapter:
         wCv: 'C_1009_AI_0005'
         xfCv: 'C_1009_AI_0006'
         pfCv: 'C_1009_AI_0007'
-        lwDpAlarm: 'C_1009_BI_0008'
-        fjUvAlarm: 'C_1009_BI_0009'
-        afAlarm: 'C_1009_BI_0010'
+        lwDpAlarm: 'C_1009_DI_0008'
+        fjUvAlarm: 'C_1009_DI_0009'
+        afAlarm: 'C_1009_DI_0010'
         xfStatus: 'C_1201_DI_0012'
         xfMA: 'C_1201_DI_0014'
         xfFault: 'C_1201_DI_0013'
@@ -185,12 +185,12 @@ adapter:
         wCv: 'C_1010_AI_0005'
         xfCv: 'C_1009_AI_0006'
         pfCv: 'C_1010_AI_0007'
-        lwDpAlarm: 'C_1010_BI_0008'
-        fjUvAlarm: 'C_1010_BI_0009'
-        afAlarm: 'C_1010_BI_0010'
+        lwDpAlarm: 'C_1010_DI_0008'
+        fjUvAlarm: 'C_1010_DI_0009'
+        afAlarm: 'C_1010_DI_0010'
         xfStatus: 'C_1201_DI_0009'
-        xfMA: 'C_1201_DI_0010'
-        xfFault: 'C_1201_DI_0011'
+        xfMA: 'C_1201_DI_0011'
+        xfFault: 'C_1201_DI_0010'
         timeStatus: 'C_1010_AV_0000,C_1010_AV_0001,C_1010_AV_0002,C_1010_AV_0003'
         xfTempSetVal: 'C_1010_AV_0004'
         LnSu: 'C_1010_BV_0009'
@@ -206,9 +206,9 @@ adapter:
         wCv: 'C_1011_AI_0005'
         xfCv: 'C_1011_AI_0006'
         pfCv: 'C_1011_AI_0007'
-        lwDpAlarm: 'C_1011_BI_0008'
-        fjUvAlarm: 'C_1011_BI_0009'
-        afAlarm: 'C_1011_BI_0010'
+        lwDpAlarm: 'C_1011_DI_0008'
+        fjUvAlarm: 'C_1011_DI_0009'
+        afAlarm: 'C_1011_DI_0010'
         xfStatus: 'C_1201_DI_0006'
         xfMA: 'C_1201_DI_0007'
         xfFault: 'C_1201_DI_0008'
@@ -227,15 +227,15 @@ adapter:
         wCv: 'C_1012_AI_0005'
         xfCv: 'C_1012_AI_0006'
         pfCv: 'C_1012_AI_0007'
-        lwDpAlarm: 'C_1012_BI_0008'
-        fjUvAlarm: 'C_1012_BI_0009'
-        afAlarm: 'C_1012_BI_0010'
-        xfStatus: 'C_1012_BI_0011'
-        xfMA: 'C_1012_BI_0012'
-        xfFault: 'C_1012_BI_0013'
-        pfStatus: 'C_1012_BI_0014'
-        pfMA: 'C_1012_BI_0015'
-        pfFault: 'C_1012_BI_0016'
+        lwDpAlarm: 'C_1012_DI_0008'
+        fjUvAlarm: 'C_1012_DI_0009'
+        afAlarm: 'C_1012_DI_0010'
+        xfStatus: 'C_1012_DI_0011'
+        xfMA: 'C_1012_DI_0012'
+        xfFault: 'C_1012_DI_0013'
+        pfStatus: 'C_1012_DI_0014'
+        pfMA: 'C_1012_DI_0015'
+        pfFault: 'C_1012_DI_0016'
         timeStatus: 'C_1012_AV_0000,C_1012_AV_0001,C_1012_AV_0002,C_1012_AV_0003'
         xfTempSetVal: 'C_1012_AV_0004'
         LnSu: 'C_1012_BV_0009'
@@ -265,12 +265,12 @@ adapter:
         hfTemp: 'C_2012_AI_0018'
         xfCv: 'C_2012_AI_0019'
         wCv: 'C_2012_AI_0020'
-        lwDpAlarm: 'C_2012_BI_0037'
-        fjUvAlarm: 'C_2012_BI_0038'
-        afAlarm: 'C_2012_BI_0039'
-        xfStatus: 'C_2012_BI_0040'
-        xfMA: 'C_2012_BI_0041'
-        xfFault: 'C_2012_BI_0042'
+        lwDpAlarm: 'C_2012_DI_0037'
+        fjUvAlarm: 'C_2012_DI_0038'
+        afAlarm: 'C_2012_DI_0039'
+        xfStatus: 'C_2012_DI_0040'
+        xfMA: 'C_2012_DI_0041'
+        xfFault: 'C_2012_DI_0042'
         timeStatus: 'C_2012_AV_0010,C_2012_AV_0011,C_2012_AV_0012,C_2012_AV_0013'
         xfTempSetVal: 'C_2012_AV_0014'
         LnSu: 'C_2012_BV_0019'
@@ -282,12 +282,12 @@ adapter:
         hfTemp: 'C_1011_AI_0018'
         xfCv: 'C_1011_AI_0019'
         wCv: 'C_1011_AI_0020'
-        lwDpAlarm: 'C_1011_BI_0037'
-        fjUvAlarm: 'C_1011_BI_0038'
-        afAlarm: 'C_1011_BI_0039'
-        xfStatus: 'C_1011_BI_0040'
-        xfMA: 'C_1011_BI_0041'
-        xfFault: 'C_1011_BI_0042'
+        lwDpAlarm: 'C_1011_DI_0037'
+        fjUvAlarm: 'C_1011_DI_0038'
+        afAlarm: 'C_1011_DI_0039'
+        xfStatus: 'C_1011_DI_0040'
+        xfMA: 'C_1011_DI_0041'
+        xfFault: 'C_1011_DI_0042'
         timeStatus: 'C_1011_AV_0010,C_1011_AV_0011,C_1011_AV_0012,C_1011_AV_0013'
         xfTempSetVal: 'C_1011_AV_0014'
         LnSu: 'C_1011_BV_0019'
@@ -313,46 +313,45 @@ adapter:
     wtMapper:
       # 北区水箱
       'Z020-B-WT-1':
-        tankLevel: 'C_2008_AI_0000'
-        highLevelAlarm: 'C_2008_BI_0001'
-        lowLevelAlarm: 'C_2008_BI_0002'
+        highLevelAlarm: 'C_2008_DI_0001'
+        lowLevelAlarm: 'C_2008_DI_0002'
       # 南区水箱
       'Z020-N-WT-1':
-        highLevelAlarm: '1008-BI0'
-        lowLevelAlarm: '1008-BI1'
+        highLevelAlarm: 'C_1008_DI_0000'
+        lowLevelAlarm: 'C_1008_DI_0001'
     wpMapper:
       # 北区1号泵
       'Z020-B-WP-1':
-        autoState: 'C_2008_BI_0006'
-        runningState: 'C_2008_BI_0007'
-        faultState: 'C_2008_BI_0008'
+        autoState: 'C_2008_DI_0006'
+        runningState: 'C_2008_DI_0007'
+        faultState: 'C_2008_DI_0008'
       # 北区2号泵
       'Z020-B-WP-2':
-        autoState: 'C_2008_BI_0003'
-        runningState: 'C_2008_BI_0004'
-        faultState: 'C_2008_BI_0005'
+        autoState: 'C_2008_DI_0003'
+        runningState: 'C_2008_DI_0004'
+        faultState: 'C_2008_DI_0005'
       # 北区1号生活泵
       'Z020-B-WP-SH-1':
-        runningState: 'C_2008_BI_0009'
-        faultState: 'C_2008_BI_0010'
+        runningState: 'C_2008_DI_0009'
+        faultState: 'C_2008_DI_0010'
       # 北区2号生活泵
       'Z020-B-WP-SH-2':
-        runningState: 'C_2008_BI_0011'
-        faultState: 'C_2008_BI_0012'
+        runningState: 'C_2008_DI_0011'
+        faultState: 'C_2008_DI_0012'
       # 北区3号生活泵
       'Z020-B-WP-SH-3':
-        runningState: 'C_2008_BI_0013'
-        faultState: 'C_2008_BI_0014'
+        runningState: 'C_2008_DI_0013'
+        faultState: 'C_2008_DI_0014'
       # 南区1号泵
       'Z020-N-WP-1':
-        autoState: '1008-BI2'
-        runningState: '1008-BI3'
-        faultState: '1008-BI4'
+        autoState: 'C_1008_DI_0002'
+        runningState: 'C_1008_DI_0003'
+        faultState: 'C_1008_DI_0004'
       # 南区2号泵
       'Z020-N-WP-2':
-        autoState: '1008-BI5'
-        runningState: '1008-BI6'
-        faultState: '1008-BI7'
+        autoState: 'C_1008_DI_0005'
+        runningState: 'C_1008_DI_0006'
+        faultState: 'C_1008_DI_0007'
     lightMapper:
       'Z020-B-LIGHT-01':
         setCtl-OnOff: 'C_8001_BV_0000'

+ 16 - 6
ems/ems-cloud/ems-server/src/main/java/com/ruoyi/ems/controller/OpEnergyStrategyController.java

@@ -373,15 +373,15 @@ public class OpEnergyStrategyController extends BaseController {
     }
 
     // ==================== 执行日志(新增) ====================
-
     /**
-     * 获取策略执行日志列表
+     * 获取策略执行日志列表(支持分页和多条件查询)
      */
-    @GetMapping("/execLog/list/{strategyCode}")
+    @GetMapping("/execLog/list")
     @ApiOperation("获取执行日志列表")
-    public AjaxResult getExecLogList(@PathVariable String strategyCode) {
-        List<OpEnergyStrategyExecLog> execLogs = execLogService.selectByStrategyCode(strategyCode);
-        return success(execLogs);
+    public TableDataInfo getExecLogList(OpEnergyStrategyExecLog param) {
+        startPage();
+        List<OpEnergyStrategyExecLog> execLogs = execLogService.selectExecLogList(param);
+        return getDataTable(execLogs);
     }
 
     /**
@@ -404,4 +404,14 @@ public class OpEnergyStrategyController extends BaseController {
 
         return success(result);
     }
+
+    /**
+     * 获取步骤执行日志
+     */
+    @GetMapping("/execLog/steps/{execId}")
+    @ApiOperation("获取步骤执行日志")
+    public AjaxResult getStepExecLog(@PathVariable String execId) {
+        List<OpEnergyStrategyStepLog> stepLogs = execLogService.selectStepLogsByExecId(execId);
+        return success(stepLogs);
+    }
 }

+ 45 - 18
ems/ems-core/src/main/java/com/ruoyi/ems/domain/OpEnergyStrategyExecLog.java

@@ -1,42 +1,69 @@
-/*
- * 文 件 名:  OpEnergyStrategyExecLog
- * 版    权:  华设设计集团股份有限公司
- * 描    述:  <描述>
- * 修 改 人:  lvwenbin
- * 修改时间:  2025/11/27
- * 跟踪单号:  <跟踪单号>
- * 修改单号:  <修改单号>
- * 修改内容:  <修改内容>
- */
 package com.ruoyi.ems.domain;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import lombok.Data;
-
 import java.util.Date;
 
 /**
- * OpEnergyStrategyExecLog
- * <功能详细描述>
- *
- * @author lvwenbin
- * @version [版本号, 2025/11/27]
- * @see [相关类/方法]
- * @since [产品/模块版本]
+ * 策略执行日志
  */
 @Data
 public class OpEnergyStrategyExecLog {
+    /** 主键ID */
     private Long id;
+
+    /** 策略代码 */
     private String strategyCode;
+
+    /** 策略名称(关联查询) */
+    private String strategyName;
+
+    /** 执行ID */
     private String execId;
+
+    /** 触发类型 */
     private String triggerType;
+
+    /** 触发源 */
     private String triggerSource;
+
+    /** 执行状态:0-执行中,1-成功,2-失败,3-超时 */
     private Integer execStatus;
+
+    /** 开始时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date startTime;
+
+    /** 结束时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date endTime;
+
+    /** 执行时长(毫秒) */
     private Integer duration;
+
+    /** 执行上下文(JSON) */
     private String contextData;
+
+    /** 执行结果(JSON) */
     private String resultData;
+
+    /** 错误信息 */
     private String errorMessage;
+
+    /** 执行人 */
     private String execBy;
+
+    /** 创建时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
+
+    // ========== 查询参数(非数据库字段) ==========
+    /** 开始时间-起始 */
+    @JsonIgnore
+    private String startTimeBegin;
+
+    /** 开始时间-结束 */
+    @JsonIgnore
+    private String startTimeEnd;
 }

+ 34 - 18
ems/ems-core/src/main/java/com/ruoyi/ems/domain/OpEnergyStrategyStepLog.java

@@ -1,43 +1,59 @@
-/*
- * 文 件 名:  OpEnergyStrategyStepLog
- * 版    权:  华设设计集团股份有限公司
- * 描    述:  <描述>
- * 修 改 人:  lvwenbin
- * 修改时间:  2025/11/27
- * 跟踪单号:  <跟踪单号>
- * 修改单号:  <修改单号>
- * 修改内容:  <修改内容>
- */
 package com.ruoyi.ems.domain;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
-
 import java.util.Date;
 
 /**
- * OpEnergyStrategyStepLog
- * <功能详细描述>
- *
- * @author lvwenbin
- * @version [版本号, 2025/11/27]
- * @see [相关类/方法]
- * @since [产品/模块版本]
+ * 策略步骤执行日志
  */
 @Data
 public class OpEnergyStrategyStepLog {
+    /** 主键ID */
     private Long id;
+
+    /** 策略执行ID */
     private String execId;
+
+    /** 策略代码 */
     private String strategyCode;
+
+    /** 步骤代码 */
     private String stepCode;
+
+    /** 步骤名称 */
     private String stepName;
+
+    /** 步骤顺序 */
     private Integer stepIndex;
+
+    /** 执行状态:0-执行中,1-成功,2-失败,3-跳过 */
     private Integer execStatus;
+
+    /** 开始时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date startTime;
+
+    /** 结束时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date endTime;
+
+    /** 执行时长(毫秒) */
     private Integer duration;
+
+    /** 输入参数 */
     private String inputParam;
+
+    /** 输出结果 */
     private String outputResult;
+
+    /** 错误信息 */
     private String errorMessage;
+
+    /** 重试次数 */
     private Integer retryCount;
+
+    /** 创建时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
 }

+ 31 - 12
ems/ems-core/src/main/resources/mapper/ems/OpEnergyStrategyExecLogMapper.xml

@@ -5,6 +5,7 @@
     <resultMap type="com.ruoyi.ems.domain.OpEnergyStrategyExecLog" id="ExecLogResult">
         <result property="id" column="id"/>
         <result property="strategyCode" column="strategy_code"/>
+        <result property="strategyName" column="strategy_name"/>
         <result property="execId" column="exec_id"/>
         <result property="triggerType" column="trigger_type"/>
         <result property="triggerSource" column="trigger_source"/>
@@ -20,40 +21,58 @@
     </resultMap>
 
     <sql id="selectExecLogVo">
-        select id, strategy_code, exec_id, trigger_type, trigger_source, exec_status,
-               start_time, end_time, duration, context_data, result_data, error_message,
-               exec_by, create_time
-        from adm_op_energy_strategy_exec_log
+        select
+            l.id, l.strategy_code, l.exec_id, l.trigger_type, l.trigger_source,
+            l.exec_status, l.start_time, l.end_time, l.duration, l.context_data,
+            l.result_data, l.error_message, l.exec_by, l.create_time,
+            s.strategy_name
+        from adm_op_energy_strategy_exec_log l
+                 left join adm_op_energy_strategy s on l.strategy_code = s.strategy_code
     </sql>
 
     <select id="selectExecLogList" parameterType="com.ruoyi.ems.domain.OpEnergyStrategyExecLog" resultMap="ExecLogResult">
         <include refid="selectExecLogVo"/>
         <where>
             <if test="strategyCode != null and strategyCode != ''">
-                and strategy_code = #{strategyCode}
+                and l.strategy_code = #{strategyCode}
             </if>
             <if test="execStatus != null">
-                and exec_status = #{execStatus}
+                and l.exec_status = #{execStatus}
+            </if>
+            <if test="triggerType != null and triggerType != ''">
+                and l.trigger_type = #{triggerType}
+            </if>
+            <if test="triggerSource != null and triggerSource != ''">
+                and l.trigger_source like concat('%', #{triggerSource}, '%')
+            </if>
+            <if test="execBy != null and execBy != ''">
+                and l.exec_by = #{execBy}
+            </if>
+            <if test="startTimeBegin != null and startTimeBegin != ''">
+                and l.start_time &gt;= #{startTimeBegin}
+            </if>
+            <if test="startTimeEnd != null and startTimeEnd != ''">
+                and l.start_time &lt;= #{startTimeEnd}
             </if>
             <if test="startTime != null">
-                and start_time &gt;= #{startTime}
+                and l.start_time &gt;= #{startTime}
             </if>
             <if test="endTime != null">
-                and end_time &lt;= #{endTime}
+                and l.end_time &lt;= #{endTime}
             </if>
         </where>
-        order by start_time desc
+        order by l.start_time desc
     </select>
 
     <select id="selectByExecId" parameterType="String" resultMap="ExecLogResult">
         <include refid="selectExecLogVo"/>
-        where exec_id = #{execId}
+        where l.exec_id = #{execId}
     </select>
 
     <select id="selectByStrategyCode" parameterType="String" resultMap="ExecLogResult">
         <include refid="selectExecLogVo"/>
-        where strategy_code = #{strategyCode}
-        order by start_time desc
+        where l.strategy_code = #{strategyCode}
+        order by l.start_time desc
         limit 100
     </select>
 

+ 10 - 9
ems/ems-core/src/main/resources/mapper/ems/OpEnergyStrategyStepLogMapper.xml

@@ -21,9 +21,10 @@
     </resultMap>
 
     <sql id="selectStepLogVo">
-        select id, exec_id, strategy_code, step_code, step_name, step_index, exec_status,
-               start_time, end_time, duration, input_param, output_result, error_message,
-               retry_count, create_time
+        select
+            id, exec_id, strategy_code, step_code, step_name, step_index,
+            exec_status, start_time, end_time, duration, input_param,
+            output_result, error_message, retry_count, create_time
         from adm_op_energy_strategy_step_log
     </sql>
 
@@ -43,13 +44,13 @@
                 and exec_status = #{execStatus}
             </if>
         </where>
-        order by step_index
+        order by step_index asc
     </select>
 
     <select id="selectByExecId" parameterType="String" resultMap="StepLogResult">
         <include refid="selectStepLogVo"/>
         where exec_id = #{execId}
-        order by step_index
+        order by step_index asc
     </select>
 
     <insert id="insertStepLog" parameterType="com.ruoyi.ems.domain.OpEnergyStrategyStepLog" useGeneratedKeys="true" keyProperty="id">
@@ -99,7 +100,7 @@
         where id = #{id}
     </update>
 
-    <insert id="insertStepLogBatch">
+    <insert id="insertStepLogBatch" parameterType="java.util.List">
         insert into adm_op_energy_strategy_step_log
         (exec_id, strategy_code, step_code, step_name, step_index, exec_status,
         start_time, end_time, duration, input_param, output_result, error_message, retry_count)
@@ -107,8 +108,8 @@
         <foreach collection="list" item="item" separator=",">
             (#{item.execId}, #{item.strategyCode}, #{item.stepCode}, #{item.stepName},
             #{item.stepIndex}, #{item.execStatus}, #{item.startTime}, #{item.endTime},
-            #{item.duration}, #{item.inputParam}, #{item.outputResult}, #{item.errorMessage},
-            #{item.retryCount})
+            #{item.duration}, #{item.inputParam}, #{item.outputResult},
+            #{item.errorMessage}, #{item.retryCount})
         </foreach>
     </insert>
-</mapper>
+</mapper>

+ 1 - 1
ems/sql/ems_init_data_test.sql

@@ -114,7 +114,7 @@ INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`,
 INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_W2_QF_GEEKOPEN', 'KeyLockCtl', '按键控制', '设置按键控制锁定/解锁', '{"type":"Options", "list":[{"key":"解锁按钮", "value":"0"},{"key":"锁定按钮", "value":"1"}]}', 1);
 INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_W2_QF_GEEKOPEN', 'settingCtl', '设备设置', '设备软重启/重置', '{"type":"Options", "list":[{"key":"软重启", "value":"restart"},{"key":"重置/恢复出厂", "value":"reset"}]}', 1);
 INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_W2_QF_GEEKOPEN', 'settAutoReport', '电量上报设置', '设置电量信息定时上报', '{"type":"Options", "list":[{"key":"关闭上报", "value":"0"},{"key":"15分钟", "value":"900"},{"key":"30分钟", "value":"1800"},{"key":"1小时", "value":"3600"}]}', 1);
-INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_W2_QF_GEEKOPEN', 'setOnState', '上电状态设置', '设置上电通断(默认关闭)', '{"type":"Options", "list":[{"key":"记忆", "value":"0"},{"key":"断开", "value":"1"},{"key":"开启", "value":"2"}]}', 1);
+INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_W2_QF_GEEKOPEN', 'setOnState', '上电状态设置', '设置上电通断(默认关闭)', '{"type":"Options", "list":[{"key":"上电记忆", "value":"0"},{"key":"上电断开", "value":"1"},{"key":"上电开启", "value":"2"}]}', 1);
 INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_W2_QF_GEEKOPEN', 'triggerSync', '数据同步', '触发设备信息同步', '{"type":"Options", "list":[{"key":"通讯同步", "value":"protocol"},{"key":"电量同步", "value":"statistic"},{"key":"状态同步", "value":"info"}]}', 1);
 
 INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_W2_QS_KEKA_86', 'on-off', '开关', '开启/关闭', '{"type":"Options", "list":[{"key":"开启", "value":"1"},{"key":"关闭", "value":"0"}]}', 1);

+ 3 - 0
ems/sql/ems_sys_data.sql

@@ -407,6 +407,9 @@ INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (2, 1152);
 INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (2, 1153);
 INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (2, 1154);
 INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (2, 1155);
+INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (2, 1170);
+INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (2, 1171);
+INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (2, 1172);
 INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (2, 1200);
 INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (2, 1201);
 INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES (2, 1202);