Browse Source

采集室内能耗同时产出测点属性、产出调用日志、装内部室内能耗能力接口

learshaw 2 weeks ago
parent
commit
c48c8bd85f

+ 77 - 0
ems/ems-cloud/ems-dev-adapter/src/main/java/com/ruoyi/ems/controller/InDoorEnergyController.java

@@ -0,0 +1,77 @@
+/*
+ * 文 件 名:  InDoorEnergyController
+ * 版    权:  华设设计集团股份有限公司
+ * 描    述:  <描述>
+ * 修 改 人:  lvwenbin
+ * 修改时间:  2025/8/18
+ * 跟踪单号:  <跟踪单号>
+ * 修改单号:  <修改单号>
+ * 修改内容:  <修改内容>
+ */
+package com.ruoyi.ems.controller;
+
+import com.ruoyi.ems.handle.InDoorEnergyHandler;
+import com.ruoyi.ems.model.AbilityPayload;
+import com.ruoyi.ems.model.CallResponse;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * 室内能耗Api
+ * <功能详细描述>
+ *
+ * @author lvwenbin
+ * @version [版本号, 2025/8/18]
+ * @see [相关类/方法]
+ * @since [产品/模块版本]
+ */
+@RestController
+@CrossOrigin(allowedHeaders = "*", allowCredentials = "false")
+@RequestMapping("/in-door-energy")
+@Api(value = "InDoorEnergyController", description = "室内能耗Api")
+public class InDoorEnergyController {
+    /**
+     * 日志
+     */
+    private static final Logger log = LoggerFactory.getLogger(InDoorEnergyController.class);
+
+    @Qualifier("inDoorEnergyHandler")
+    @Resource
+    private InDoorEnergyHandler inDoorEnergyHandler;
+
+    /**
+     * 常泰室内能耗能力调用
+     *
+     * @return 数据列表
+     */
+    @RequestMapping(value = "/ct/abilityCall", method = RequestMethod.POST)
+    @ApiOperation(value = "/ct/abilityCall", notes = "常泰室内能耗能力调用")
+    @ApiResponses({ @ApiResponse(code = 200, message = "success"),
+        @ApiResponse(code = 400, message = "{code:****,message:'fail'}")
+    })
+    public CallResponse<Void> ctIdeAbilityCall(@RequestBody AbilityPayload abilityPayload) {
+        CallResponse<Void> res = null;
+
+        try {
+            res = inDoorEnergyHandler.call(abilityPayload);
+        }
+        catch (Exception e) {
+            log.error("ctIdeAbilityCall fail!", e);
+            res = new CallResponse<>(501, "内部错误:" + e.getMessage());
+        }
+
+        return res;
+    }
+}

+ 4 - 11
ems/ems-cloud/ems-dev-adapter/src/main/java/com/ruoyi/ems/core/InDoorEnergyTemplate.java

@@ -16,7 +16,6 @@ import com.huashe.common.exception.Assert;
 import com.ruoyi.common.core.utils.SpringUtils;
 import com.ruoyi.common.redis.service.RedisService;
 import com.ruoyi.ems.config.InDoorEnergyConfig;
-import com.ruoyi.ems.model.idenergy.CodesVal;
 import com.ruoyi.ems.model.idenergy.CodesValReq;
 import com.ruoyi.ems.model.idenergy.Token;
 import com.ruoyi.ems.retrofit.InDoorEnergyApi;
@@ -27,7 +26,6 @@ import retrofit2.Call;
 import retrofit2.Response;
 import retrofit2.Retrofit;
 
-import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -167,8 +165,8 @@ public class InDoorEnergyTemplate extends BaseApiTemplate {
      * @param req 请求
      * @return 能耗数据列表
      */
-    public List<CodesVal> getCodesVal(CodesValReq req) {
-        List<CodesVal> retList = null;
+    public String getCodesVal(CodesValReq req) {
+        String ret = null;
 
         try {
             String token = getToken();
@@ -178,17 +176,12 @@ public class InDoorEnergyTemplate extends BaseApiTemplate {
             Response<String> response = call.execute();
             log.debug("getCodesVal response:{}", response);
 
-            JSONObject resJson = JSONObject.parseObject(response.body());
-            Assert.isTrue(StringUtils.equals(resJson.getString("code"), "200"), resJson.getInteger("code"),
-                resJson.getString("error"));
-
-            String dataStr = resJson.getString("ResultPointObjArr");
-            retList = JSONObject.parseArray(dataStr, CodesVal.class);
+            ret = response.body();
         }
         catch (Exception e) {
             log.error("getCodesVal fail!", e);
         }
 
-        return retList;
+        return ret;
     }
 }

+ 16 - 0
ems/ems-cloud/ems-dev-adapter/src/main/java/com/ruoyi/ems/handle/BaseDevHandler.java

@@ -12,6 +12,7 @@ package com.ruoyi.ems.handle;
 
 import com.huashe.common.utils.DateUtils;
 import com.ruoyi.ems.domain.EmsDevice;
+import com.ruoyi.ems.domain.EmsObjAbility;
 import com.ruoyi.ems.domain.EmsObjAbilityCallLog;
 import com.ruoyi.ems.domain.EmsObjEventLog;
 import com.ruoyi.ems.domain.EmsObjReportLog;
@@ -184,6 +185,21 @@ public abstract class BaseDevHandler {
         objAbilityCallLogService.updateLog(objAbilityCallLog);
     }
 
+    protected EmsObjAbilityCallLog saveCallLog(String objCode, EmsObjAbility objAbility, Integer callStatus,
+        String callPayload, String resPayload) {
+        EmsObjAbilityCallLog objAbilityCallLog = new EmsObjAbilityCallLog();
+        objAbilityCallLog.setObjCode(objCode);
+        objAbilityCallLog.setModelCode(objAbility.getModelCode());
+        objAbilityCallLog.setAbilityKey(objAbility.getAbilityKey());
+        objAbilityCallLog.setCallTime(new Date());
+        objAbilityCallLog.setCallPayload(callPayload);
+        objAbilityCallLog.setCallStatus(callStatus);
+        objAbilityCallLog.setResTime(new Date());
+        objAbilityCallLog.setResPayload(resPayload);
+        objAbilityCallLogService.addLog(objAbilityCallLog);
+        return objAbilityCallLog;
+    }
+
     protected void saveReportLog(String objCode, String modelCode, String msgDesc, String payload) {
         EmsObjReportLog objReportLog = new EmsObjReportLog();
         objReportLog.setObjCode(objCode);

+ 176 - 27
ems/ems-cloud/ems-dev-adapter/src/main/java/com/ruoyi/ems/handle/InDoorEnergyHandler.java

@@ -10,21 +10,29 @@
  */
 package com.ruoyi.ems.handle;
 
+import com.alibaba.fastjson.JSONObject;
+import com.huashe.common.exception.Assert;
 import com.huashe.common.utils.DateUtils;
 import com.ruoyi.ems.config.InDoorEnergyConfig;
 import com.ruoyi.ems.core.InDoorEnergyTemplate;
 import com.ruoyi.ems.domain.ElecMeterH;
 import com.ruoyi.ems.domain.EmsDevice;
+import com.ruoyi.ems.domain.EmsObjAbility;
 import com.ruoyi.ems.domain.FdEnergyPriceConfig;
 import com.ruoyi.ems.domain.MeterDevice;
 import com.ruoyi.ems.domain.WaterMeterH;
 import com.ruoyi.ems.model.AbilityPayload;
 import com.ruoyi.ems.model.CallResponse;
+import com.ruoyi.ems.model.ObjAttrTableItem;
 import com.ruoyi.ems.model.Price;
 import com.ruoyi.ems.model.QueryDevice;
 import com.ruoyi.ems.model.idenergy.CodesVal;
 import com.ruoyi.ems.model.idenergy.CodesValReq;
+import com.ruoyi.ems.domain.EmsObjAttrValue;
+import com.ruoyi.ems.service.IEmsObjAttrValueService;
+import com.alibaba.fastjson.JSON;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
@@ -32,9 +40,12 @@ import org.springframework.stereotype.Service;
 import javax.annotation.Resource;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -54,6 +65,9 @@ public class InDoorEnergyHandler extends BaseMeterDevHandler {
     private static final String MODE_CODE = "M_W2_SM_INDOOR_ENERGY";
 
     @Resource
+    private IEmsObjAttrValueService objAttrValueService;
+
+    @Resource
     private InDoorEnergyConfig config;
 
     @Override
@@ -63,7 +77,44 @@ public class InDoorEnergyHandler extends BaseMeterDevHandler {
 
     @Override
     public CallResponse<Void> call(AbilityPayload abilityParam) {
-        return null;
+        CallResponse<Void> callResponse = null;
+
+        if (StringUtils.equals("MeterReadingGw", abilityParam.getAbilityKey())) {
+            // 查询当前设备的接口属性值
+            List<EmsObjAttrValue> attrValues = objAttrValueService.selectByObjCode(MODE_CODE,
+                abilityParam.getObjCode());
+            attrValues = attrValues.stream()
+                // 过滤条件:attrKey以"interface"开头
+                .filter(attr -> StringUtils.startsWith(attr.getAttrKey(), "interface"))
+                // 收集为新的List
+                .collect(Collectors.toList());
+
+            Set<String> pointIdSet = getPointIds(attrValues);
+            CodesValReq req = new CodesValReq(pointIdSet);
+
+            // 调用能耗数据接口获取实时数据
+            InDoorEnergyTemplate template = new InDoorEnergyTemplate(config.getUrl());
+            String callRes = template.getCodesVal(req);
+            JSONObject resJson = JSONObject.parseObject(callRes);
+            Assert.isTrue(StringUtils.equals(resJson.getString("code"), "200"), resJson.getInteger("code"),
+                resJson.getString("error"));
+            EmsObjAbility ability = new EmsObjAbility();
+            ability.setModelCode(MODE_CODE);
+            ability.setAbilityKey("MeterReadingGw");
+            int callStatus = StringUtils.equals(resJson.getString("code"), "200") ? 0 : 2;
+            saveCallLog(abilityParam.getObjCode(), ability, callStatus, JSON.toJSONString(req), callRes);
+
+            String dataStr = resJson.getString("ResultPointObjArr");
+            List<CodesVal> retList = JSONObject.parseArray(dataStr, CodesVal.class);
+            // 更新设备属性
+            updateDeviceAttrList(attrValues, retList);
+            callResponse = new CallResponse<>(0, "成功");
+        }
+        else {
+            callResponse = new CallResponse<>(-1, "不支持的能力key:" + abilityParam.getAbilityKey());
+        }
+
+        return callResponse;
     }
 
     @Override
@@ -86,42 +137,83 @@ public class InDoorEnergyHandler extends BaseMeterDevHandler {
         int cnt = 0;
 
         try {
-            List<MeterDevice> deviceList = getMeterDeviceList();
+            // 获取所有能源设备列表
+            List<EmsDevice> deviceList = getDeviceList();
+            List<MeterDevice> meterDeviceList = getMeterDeviceList();
 
+            // 遍历每个能源设备
             if (CollectionUtils.isNotEmpty(deviceList)) {
-                List<String> deviceCodes = deviceList.stream().map(MeterDevice::getDeviceCode)  // 提取deviceCode属性
-                    .collect(Collectors.toList());
-
-                CodesValReq req = new CodesValReq(deviceCodes);
+                // 调用能耗数据接口获取实时数据
                 InDoorEnergyTemplate template = new InDoorEnergyTemplate(config.getUrl());
-                List<CodesVal> retList = template.getCodesVal(req);
-
-                // 电表过滤
-                List<MeterDevice> elecDevs = deviceList.stream()
-                    .filter(device -> device.getMeterCls() != null && device.getMeterCls() == 45)
-                    .collect(Collectors.toList());
 
-                // 电表抄表数据保存
-                if (CollectionUtils.isNotEmpty(elecDevs)) {
-                    cnt += saveElecMeterReading(elecDevs, retList);
+                for (EmsDevice emsDevice : deviceList) {
+                    cnt += meterDevHourProd(template, emsDevice, meterDeviceList);
                 }
+            }
+        }
+        catch (Exception e) {
+            log.error("能耗数据抄报异常", e);
+        }
 
-                // 水表过滤
-                List<MeterDevice> waterDevs = deviceList.stream()
-                    .filter(device -> device.getMeterCls() != null && device.getMeterCls() == 70)
-                    .collect(Collectors.toList());
+        return cnt;
+    }
 
-                // 水表抄表数据保存
-                if (CollectionUtils.isNotEmpty(waterDevs)) {
-                    cnt += saveWaterMeterReading(waterDevs, retList);
-                }
+    private int meterDevHourProd(InDoorEnergyTemplate template, EmsDevice emsDevice,
+        List<MeterDevice> meterDeviceList) {
+        int cnt = 0;
+
+        try {
+            // 查询当前设备的接口属性值
+            List<EmsObjAttrValue> attrValues = objAttrValueService.selectByObjCode(MODE_CODE,
+                emsDevice.getDeviceCode());
+            attrValues = attrValues.stream()
+                // 过滤条件:attrKey以"interface"开头
+                .filter(attr -> StringUtils.startsWith(attr.getAttrKey(), "interface"))
+                // 收集为新的List
+                .collect(Collectors.toList());
+
+            Set<String> pointIdSet = getPointIds(attrValues);
+            CodesValReq req = new CodesValReq(pointIdSet);
+
+            // 调用能耗数据接口获取实时数据
+            String callRes = template.getCodesVal(req);
+            JSONObject resJson = JSONObject.parseObject(callRes);
+            Assert.isTrue(StringUtils.equals(resJson.getString("code"), "200"), resJson.getInteger("code"),
+                resJson.getString("error"));
+            EmsObjAbility ability = new EmsObjAbility();
+            ability.setModelCode(MODE_CODE);
+            ability.setAbilityKey("MeterReadingGw");
+            int callStatus = StringUtils.equals(resJson.getString("code"), "200") ? 0 : 2;
+            saveCallLog(emsDevice.getDeviceCode(), ability, callStatus, JSON.toJSONString(req), callRes);
+
+            String dataStr = resJson.getString("ResultPointObjArr");
+            List<CodesVal> retList = JSONObject.parseArray(dataStr, CodesVal.class);
+
+            // 电表过滤
+            List<MeterDevice> elecDevs = meterDeviceList.stream()
+                .filter(device -> pointIdSet.contains(device.getDeviceCode()) && 45 == device.getMeterCls())
+                .collect(Collectors.toList());
+
+            // 电表抄表数据保存
+            if (CollectionUtils.isNotEmpty(elecDevs)) {
+                cnt += saveElecMeterReading(elecDevs, retList);
+            }
 
-                // 更新设备属性
-                updateDeviceAttr(retList);
+            // 水表过滤
+            List<MeterDevice> waterDevs = meterDeviceList.stream()
+                .filter(device -> pointIdSet.contains(device.getDeviceCode()) && 70 == device.getMeterCls())
+                .collect(Collectors.toList());
+
+            // 水表抄表数据保存
+            if (CollectionUtils.isNotEmpty(waterDevs)) {
+                cnt += saveWaterMeterReading(waterDevs, retList);
             }
+
+            // 更新设备属性
+            updateDeviceAttrList(attrValues, retList);
         }
         catch (Exception e) {
-            log.error("能耗数据抄报异常", e);
+            log.error("meterDevHourProd error! deviceCode:{}", emsDevice.getDeviceCode(), e);
         }
 
         return cnt;
@@ -198,6 +290,63 @@ public class InDoorEnergyHandler extends BaseMeterDevHandler {
         return CollectionUtils.isNotEmpty(meterHList) ? waterMeterHService.insertBatch(meterHList) : 0;
     }
 
-    private void updateDeviceAttr(List<CodesVal> retList) {
+    private void updateDeviceAttrList(List<EmsObjAttrValue> attrValues, List<CodesVal> retList) {
+        try {
+            Map<String, CodesVal> codesValMap = retList.stream()
+                .collect(Collectors.toMap(CodesVal::getPointId, Function.identity()));
+
+            for (EmsObjAttrValue objAttr : attrValues) {
+                // 更新列表中的值
+                boolean updated = false;
+                String attrValue = objAttr.getAttrValue();
+                List<ObjAttrTableItem> tableItems = JSON.parseArray(attrValue, ObjAttrTableItem.class);
+
+                if (CollectionUtils.isNotEmpty(tableItems)) {
+                    Map<String, ObjAttrTableItem> itemMap = tableItems.stream()
+                        .collect(Collectors.toMap(ObjAttrTableItem::getKey, Function.identity()));
+
+                    for (Map.Entry<String, ObjAttrTableItem> itemEntry : itemMap.entrySet()) {
+                        String itemKey = itemEntry.getKey();
+                        ObjAttrTableItem item = itemEntry.getValue();
+
+                        if (codesValMap.containsKey(itemKey)) {
+                            updated = true;
+                            CodesVal codesVal = codesValMap.get(itemKey);
+                            item.setValue(codesVal.getValue());
+                            item.setUpdateTime(codesVal.getTime());
+                        }
+                    }
+                }
+
+                // 如果有更新,则保存回数据库
+                if (updated) {
+                    attrValue = JSON.toJSONString(tableItems);
+                    objAttr.setAttrValue(attrValue);
+                    objAttrValueService.updateObjAttrValue(objAttr);
+                }
+            }
+        }
+        catch (Exception e) {
+            log.error("更新设备属性异常", e);
+        }
+    }
+
+    private Set<String> getPointIds(List<EmsObjAttrValue> attrValues) {
+        Set<String> pointIds = new HashSet<>();
+
+        if (CollectionUtils.isNotEmpty(attrValues)) {
+            for (EmsObjAttrValue objAttr : attrValues) {
+                String attrValue = objAttr.getAttrValue();
+                List<ObjAttrTableItem> tableItems = JSON.parseArray(attrValue, ObjAttrTableItem.class);
+
+                if (CollectionUtils.isNotEmpty(tableItems)) {
+                    List<String> tmpList = tableItems.stream().map(ObjAttrTableItem::getKey)
+                        .collect(Collectors.toList());
+                    pointIds.addAll(tmpList);
+                }
+            }
+        }
+
+        return pointIds;
     }
 }

+ 5 - 3
ems/ems-cloud/ems-dev-adapter/src/main/java/com/ruoyi/ems/model/idenergy/CodesValReq.java

@@ -13,7 +13,9 @@ package com.ruoyi.ems.model.idenergy;
 import lombok.Data;
 
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * WEB TALK 实时数据
@@ -26,16 +28,16 @@ import java.util.List;
  */
 @Data
 public class CodesValReq {
-    private List<String> codes;
+    private Set<String> codes;
 
     public CodesValReq() {
     }
 
-    public CodesValReq(List<String> codes) {
+    public CodesValReq(Set<String> codes) {
         this.codes = codes;
     }
 
     public CodesValReq(String... codes) {
-        this.codes = Arrays.asList(codes);
+        this.codes = new HashSet<>(Arrays.asList(codes));
     }
 }

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

@@ -33,7 +33,7 @@ spring:
         # 主库数据源
         master:
           driver-class-name: com.mysql.cj.jdbc.Driver
-          url: jdbc:mysql://192.168.20.210:3306/ems_ct_test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+          url: jdbc:mysql://192.168.20.210:3306/ems_ct?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
           username: root
           password: root
           # 从库数据源

+ 2 - 4
ems/ems-cloud/ems-dev-adapter/src/test/java/com/huashe/test/InDoorEnergyTest.java

@@ -14,7 +14,6 @@ import com.ruoyi.ems.EmsDevAdpApplication;
 import com.ruoyi.ems.config.InDoorEnergyConfig;
 import com.ruoyi.ems.core.InDoorEnergyTemplate;
 import com.ruoyi.ems.handle.InDoorEnergyHandler;
-import com.ruoyi.ems.model.idenergy.CodesVal;
 import com.ruoyi.ems.model.idenergy.CodesValReq;
 import lombok.extern.slf4j.Slf4j;
 import org.junit.Assert;
@@ -24,7 +23,6 @@ import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 
 import javax.annotation.Resource;
-import java.util.List;
 
 /**
  * 室内能耗采集单元测试
@@ -67,7 +65,7 @@ public class InDoorEnergyTest {
     @Test
     public void testGetCodesVal() {
         InDoorEnergyTemplate template = new InDoorEnergyTemplate(config.getUrl());
-        List<CodesVal> retList = template.getCodesVal(new CodesValReq("C_2003_AV_0000", "C_2003_AV_0002"));
-        Assert.assertNotNull(retList);
+        String ret = template.getCodesVal(new CodesValReq("C_2003_AV_0000", "C_2003_AV_0002"));
+        Assert.assertNotNull(ret);
     }
 }

+ 1 - 1
ems/ems-core/src/main/java/com/ruoyi/ems/domain/EmsObjAttrValue.java

@@ -10,7 +10,7 @@ import java.util.Date;
  * 能源对象属性值对象 adm_ems_obj_attr_value
  *
  * @author ruoyi
- * @date 2024-09-25
+ * @date 2024-09-25  List<EmsObjAttrValue>
  */
 public class EmsObjAttrValue {
     /**

+ 10 - 2
ems/ems-core/src/main/java/com/ruoyi/ems/mapper/EmsObjAttrValueMapper.java

@@ -32,7 +32,7 @@ public interface EmsObjAttrValueMapper {
      * 查询能源对象属性值列表
      *
      * @param modelCode 对象类型
-     * @param objCode 对象代码
+     * @param objCode   对象代码
      * @return 能源对象属性值集合
      */
     List<EmsObjAttrValue> selectByObjCode(@Param("modelCode") String modelCode, @Param("objCode") String objCode);
@@ -46,6 +46,14 @@ public interface EmsObjAttrValueMapper {
     int replaceObjAttrValue(EmsObjAttrValue objAttrValue);
 
     /**
+     * 更新能源对象属性值
+     *
+     * @param objAttrValue 能源对象属性值
+     * @return 结果
+     */
+    int updateObjAttrValue(EmsObjAttrValue objAttrValue);
+
+    /**
      * 批量新增能源对象属性值
      *
      * @param list 能源对象属性值
@@ -57,7 +65,7 @@ public interface EmsObjAttrValueMapper {
      * 删除能源对象属性值
      *
      * @param modelCode 对象模型
-     * @param objCode 对象代码
+     * @param objCode   对象代码
      * @return 结果
      */
     int deleteByObjCode(@Param("modelCode") String modelCode, @Param("objCode") String objCode);

+ 66 - 0
ems/ems-core/src/main/java/com/ruoyi/ems/model/ObjAttrTableItem.java

@@ -0,0 +1,66 @@
+/*
+ * 文 件 名:  ObjAttrTableItem
+ * 版    权:  华设设计集团股份有限公司
+ * 描    述:  <描述>
+ * 修 改 人:  lvwenbin
+ * 修改时间:  2025/8/18
+ * 跟踪单号:  <跟踪单号>
+ * 修改单号:  <修改单号>
+ * 修改内容:  <修改内容>
+ */
+package com.ruoyi.ems.model;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.util.Date;
+
+/**
+ * 对象属性值表格方式的记录
+ * <功能详细描述>
+ *
+ * @author lvwenbin
+ * @version [版本号, 2025/8/18]
+ * @see [相关类/方法]
+ * @since [产品/模块版本]
+ */
+public class ObjAttrTableItem {
+    private String name;
+
+    private String key;
+
+    private String value;
+
+    private String updateTime;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public String getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(String updateTime) {
+        this.updateTime = updateTime;
+    }
+}

+ 7 - 0
ems/ems-core/src/main/java/com/ruoyi/ems/service/IEmsObjAttrValueService.java

@@ -45,6 +45,13 @@ public interface IEmsObjAttrValueService {
     int mergeObjAttrValue(EmsObjAttrValue objAttrValue);
 
     /**
+     * 更新能源对象属性值
+     * @param objAttrValue 能源对象属性
+     * @return 结果
+     */
+    int updateObjAttrValue(EmsObjAttrValue objAttrValue);
+
+    /**
      * 批量新增能源对象属性值
      *
      * @param list 能源对象属性值

+ 5 - 0
ems/ems-core/src/main/java/com/ruoyi/ems/service/impl/EmsObjAttrValueServiceImpl.java

@@ -58,6 +58,11 @@ public class EmsObjAttrValueServiceImpl implements IEmsObjAttrValueService {
     }
 
     @Override
+    public int updateObjAttrValue(EmsObjAttrValue objAttrValue) {
+        return objAttrValueMapper.updateObjAttrValue(objAttrValue);
+    }
+
+    @Override
     public int insertBatch(List<EmsObjAttrValue> list) {
         EmsObjAttrValue objAttrValue = list.get(0);
         objAttrValueMapper.deleteByObjCode(objAttrValue.getModelCode(), objAttrValue.getObjCode());

+ 6 - 0
ems/ems-core/src/main/resources/mapper/ems/EmsObjAttrValueMapper.xml

@@ -52,6 +52,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
          </trim>
     </update>
 
+    <update id="updateObjAttrValue" parameterType="com.ruoyi.ems.domain.EmsObjAttrValue">
+        update adm_ems_obj_attr_value
+            set attr_value = #{attrValue}
+        where obj_code = #{objCode} and model_code = #{modelCode} and attr_key = #{attrKey}
+    </update>
+
     <insert id="insertBatch" parameterType="java.util.List" >
         insert into adm_ems_obj_attr_value (obj_code, model_code, attr_key, attr_value)
         values

+ 1 - 1
ems/ems-core/src/main/resources/mapper/ems/WaterMeterHMapper.xml

@@ -131,7 +131,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         delete from adm_water_meter_h where `date` = #{date}
     </delete>
 
-    <select id="selectLatelyItem" parameterType="java.lang.String" resultMap="WaterMeterResult">
+    <select id="selectLatelyItem" parameterType="java.lang.String" resultMap="WaterMeterHResult">
         <include refid="selectWaterMeterHVo"/>
         where device_code = #{deviceCode}
         ORDER BY record_time desc limit 1

+ 5 - 3
ems/sql/ems_init_data.sql

@@ -229,9 +229,9 @@ INSERT INTO `adm_op_energy_strategy_param` (`strategy_code`, `param_group`, `par
 
 
 -- 对象模型表
-INSERT INTO `adm_ems_obj_model` (`model_code`, `model_name`, `obj_type`, `ability_handler`, `event_handler`) VALUES ('M_W2_SM_INDOOR_ENERGY', '室内能耗计量终端', 2, 'http://192.168.20.210:9203/ems-dev-adapter/sm/inDoorEnergy/abilityCall', NULL);
-INSERT INTO `adm_ems_obj_model` (`model_code`, `model_name`, `obj_type`, `ability_handler`, `event_handler`) VALUES ('M_W2_QF_GEEKOPEN', 'GeekOpen断路器', 2, 'http://192.168.20.210:9203/ems-dev-adapter/circuit-breaker/GeekOpen/abilityCall', NULL);
-INSERT INTO `adm_ems_obj_model` (`model_code`, `model_name`, `obj_type`, `ability_handler`, `event_handler`) VALUES ('M_W2_QS_KEKA_86', 'KEKA开关(86型)', 2, 'http://192.168.20.210:9203/ems-dev-adapter/button-switch/keka/86ButtonSwitchCall', NULL);
+INSERT INTO `adm_ems_obj_model` (`model_code`, `model_name`, `obj_type`, `ability_handler`, `event_handler`) VALUES ('M_W2_SM_INDOOR_ENERGY', '室内能耗计量终端', 2, 'http://172.17.60.27:9203/ems-dev-adapter/in-door-energy/ct/abilityCall', NULL);
+INSERT INTO `adm_ems_obj_model` (`model_code`, `model_name`, `obj_type`, `ability_handler`, `event_handler`) VALUES ('M_W2_QF_GEEKOPEN', 'GeekOpen断路器', 2, 'http://172.17.60.27:9203/ems-dev-adapter/circuit-breaker/GeekOpen/abilityCall', NULL);
+INSERT INTO `adm_ems_obj_model` (`model_code`, `model_name`, `obj_type`, `ability_handler`, `event_handler`) VALUES ('M_W2_QS_KEKA_86', 'KEKA开关(86型)', 2, 'http://172.17.60.27:9203/ems-dev-adapter/button-switch/keka/86ButtonSwitchCall', NULL);
 
 -- 对象属性数据
 INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_W2_SM_INDOOR_ENERGY', 'Base', 'ip', '网络地址', NULL, 'String');
@@ -354,6 +354,8 @@ INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `at
 
 
 -- 对象能力DEMO数据
+INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `ability_param`, `hidden_flag`) VALUES ('M_W2_SM_INDOOR_ENERGY', 'MeterReadingGw', '实时抄报-网关', '网关-测点批量抄报', null, 1);
+
 INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `ability_param`, `hidden_flag`) VALUES ('M_W2_QF_GEEKOPEN', 'Circuit-Closing', '分闸', '控制线路断电', '{\"type\":\"event\",\"key\":0}', 1);
 INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `ability_param`, `hidden_flag`) VALUES ('M_W2_QF_GEEKOPEN', 'Circuit-Opening', '合闸', '控制线路通电', '{\"type\":\"event\",\"key\":1}', 1);
 INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `ability_param`, `hidden_flag`) VALUES ('M_W2_QF_GEEKOPEN', 'Key-Lock', '按键解锁', '设置按键控制锁-关闭', '{\"type\":\"setting\",\"keyLock\":0}', 1);