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

+ 17 - 7
ems/ems-cloud/ems-dev-adapter/src/main/java/com/ruoyi/ems/TaskExecutor.java

@@ -14,6 +14,7 @@ import com.ruoyi.ems.core.ObjectCache;
 import com.ruoyi.ems.handle.AcrelElecMonitorHandler;
 import com.ruoyi.ems.handle.BaCtlHandler;
 import com.ruoyi.ems.handle.GeekOpenCbHandler;
+import com.ruoyi.ems.handle.GrowattHandler;
 import com.ruoyi.ems.handle.SquareLightCtlHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -60,6 +61,10 @@ public class TaskExecutor {
     @Resource
     private AcrelElecMonitorHandler acrelElecMonitorHandler;
 
+    @Qualifier("growattHandler")
+    @Resource
+    private GrowattHandler growattHandler;
+
     /**
      * 定时清理过期设备上报响应
      */
@@ -75,8 +80,9 @@ public class TaskExecutor {
     @Scheduled(cron = "0 0/5 * * * ?")
     public void refresh5min() {
         CompletableFuture.runAsync(() -> squareLightCtlHandler.execSyncDevAttrAll());
+        CompletableFuture.runAsync(() -> squareLightCtlHandler.refreshOnline());
         CompletableFuture.runAsync(() -> acrelElecMonitorHandler.execSyncDevAttrAll());
-        squareLightCtlHandler.refreshOnline();
+        CompletableFuture.runAsync(() -> growattHandler.refreshOnline());
     }
 
 //    /**
@@ -93,12 +99,16 @@ public class TaskExecutor {
      */
     @Scheduled(cron = "0 0/15 * * * ?")
     public void baMeterCollect() {
-        baCtlHandler.meterCollect();
-        baCtlHandler.xfCollect();
-        baCtlHandler.ahuCollect();
-        baCtlHandler.wtCollect();
-        baCtlHandler.wpCollect();
-        baCtlHandler.lightCollect();
+        CompletableFuture.runAsync(() -> {
+            baCtlHandler.meterCollect();
+            baCtlHandler.xfCollect();
+            baCtlHandler.ahuCollect();
+            baCtlHandler.wtCollect();
+            baCtlHandler.wpCollect();
+            baCtlHandler.lightCollect();
+        });
+
+        CompletableFuture.runAsync(() -> growattHandler.execCollectInverterData());
     }
 
     /**

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

@@ -0,0 +1,77 @@
+/*
+ * 文 件 名:  GrowattController
+ * 版    权:  华设设计集团股份有限公司
+ * 描    述:  <描述>
+ * 修 改 人:  lvwenbin
+ * 修改时间:  2025/12/18
+ * 跟踪单号:  <跟踪单号>
+ * 修改单号:  <修改单号>
+ * 修改内容:  <修改内容>
+ */
+package com.ruoyi.ems.controller;
+
+import com.ruoyi.ems.handle.GrowattHandler;
+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;
+
+/**
+ * 古瑞瓦特光伏适配
+ * <功能详细描述>
+ *
+ * @author lvwenbin
+ * @version [版本号, 2025/12/18]
+ * @see [相关类/方法]
+ * @since [产品/模块版本]
+ */
+@RestController
+@CrossOrigin(allowedHeaders = "*", allowCredentials = "false")
+@RequestMapping("/growatt")
+@Api(value = "GrowattController", description = "古瑞瓦特-光伏适配接口")
+public class GrowattController {
+    /**
+     * 日志
+     */
+    private static final Logger log = LoggerFactory.getLogger(GrowattController.class);
+
+    @Qualifier("growattHandler")
+    @Resource
+    private GrowattHandler growattHandler;
+
+    /**
+     * 采集器能力调用
+     *
+     * @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> call(@RequestBody AbilityPayload abilityPayload) {
+        CallResponse<Void> res = null;
+
+        try {
+            res = growattHandler.call(abilityPayload);
+        }
+        catch (Exception e) {
+            log.error("call fail!", e);
+            res = new CallResponse<>(501, "内部错误:" + e.getMessage());
+        }
+
+        return res;
+    }
+}

+ 8 - 13
ems/ems-cloud/ems-dev-adapter/src/main/java/com/ruoyi/ems/core/GrowattTemplate.java

@@ -10,8 +10,9 @@
  */
 package com.ruoyi.ems.core;
 
-import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.support.retrofit.Retrofit2ConverterFactory;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
 import com.huashe.common.exception.Assert;
 import com.ruoyi.ems.model.growatt.DataLogger;
 import com.ruoyi.ems.model.growatt.DeviceInfo;
@@ -24,9 +25,7 @@ import retrofit2.Response;
 import retrofit2.Retrofit;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 /**
  * Growatt - 古瑞瓦特 操作模板
@@ -114,7 +113,7 @@ public class GrowattTemplate extends BaseApiTemplate {
 
                 if (null != data) {
                     String dataStr = data.getString("dataloggers");
-                    list.addAll(JSONObject.parseArray(dataStr, DataLogger.class));
+                    list.addAll(JSON.parseArray(dataStr, DataLogger.class));
 
                     int count = data.getIntValue("count");
                     isLastPage = list.size() >= count;
@@ -162,7 +161,7 @@ public class GrowattTemplate extends BaseApiTemplate {
 
                 if (null != data) {
                     String dataStr = data.getString("devices");
-                    list.addAll(JSONObject.parseArray(dataStr, DeviceInfo.class));
+                    list.addAll(JSON.parseArray(dataStr, DeviceInfo.class));
 
                     int count = data.getIntValue("count");
                     isLastPage = list.size() >= count;
@@ -188,8 +187,8 @@ public class GrowattTemplate extends BaseApiTemplate {
      * @param snList 设备SN集合
      * @return 设备列表
      */
-    public Map<String, Object> getDeviceData(int type, List<String> snList) {
-        Map<String, Object> retMap = new HashMap<>();
+    public JSONObject getDeviceData(int type, List<String> snList) {
+        JSONObject retJson = null;
 
         try {
             // 执行调用
@@ -203,16 +202,12 @@ public class GrowattTemplate extends BaseApiTemplate {
             Assert.isTrue(resJson.getIntValue("error_code") == 0, resJson.getIntValue("error_code"),
                 resJson.getString("error_msg"));
 
-            JSONObject data = resJson.getJSONObject("data");
-
-            if (null != data) {
-                retMap = data.getInnerMap();
-            }
+            retJson = resJson.getJSONObject("data");
         }
         catch (Exception e) {
             log.error("getDeviceData fail!", e);
         }
 
-        return retMap;
+        return retJson;
     }
 }

+ 83 - 77
ems/ems-cloud/ems-dev-adapter/src/main/java/com/ruoyi/ems/handle/BaCtlHandler.java

@@ -27,7 +27,6 @@ import com.ruoyi.ems.model.idenergy.CodesVal;
 import com.ruoyi.ems.model.idenergy.CodesValReq;
 import com.ruoyi.ems.model.idenergy.CodesValSetReq;
 import com.ruoyi.ems.service.IEmsObjAttrValueService;
-import com.ruoyi.ems.util.PingUtils;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
@@ -60,9 +59,6 @@ import java.util.stream.Collectors;
 public class BaCtlHandler extends BaseMeterDevHandler {
     private static final Logger log = LoggerFactory.getLogger(BaCtlHandler.class);
 
-    // 对接系统
-    private static final String SYS_MODE_CODE = "M_W4_SYS_BA";
-
     // 网关模型代码
     private static final String GATEWAY_MODEL = "M_W4_DEV_BA_GA";
 
@@ -173,26 +169,33 @@ public class BaCtlHandler extends BaseMeterDevHandler {
                 callResponse = new CallResponse<>(0, "成功");
             }
             else if (DevObjType.DEVC.getCode() == param.getObjType()) {
-                if (StringUtils.equals("MeterReadingGw", param.getAbilityKey()) && StringUtils.equals(param.getModelCode(), GATEWAY_MODEL)) {
+                if (StringUtils.equals("MeterReadingGw", param.getAbilityKey()) && StringUtils.equals(
+                    param.getModelCode(), GATEWAY_MODEL)) {
                     meterReadingGw(param.getModelCode(), param.getAbilityKey(), param.getObjCode());
                 }
-                else if (StringUtils.equals("StartStopCtl", param.getAbilityKey()) && StringUtils.equals(param.getModelCode(), METER_MODEL_XF)) {
+                else if (StringUtils.equals("StartStopCtl", param.getAbilityKey()) && StringUtils.equals(
+                    param.getModelCode(), METER_MODEL_XF)) {
                     Map<String, String> xfMapper = config.getXfMapper();
                     String pointId = xfMapper.get(String.format("%s.%s", param.getObjCode(), "setCtl-StartStop"));
                     Assert.notEmpty(pointId, -1, "该设备未配置控制测点pointId.");
-                    devAbilityCall(METER_MODEL_XF, param.getObjCode(), pointId, param.getAbilityKey(), param.getAbilityParam());
+                    devAbilityCall(METER_MODEL_XF, param.getObjCode(), pointId, param.getAbilityKey(),
+                        param.getAbilityParam());
                 }
-                else if (StringUtils.equals("StartStopCtl", param.getAbilityKey()) && StringUtils.equals(param.getModelCode(), METER_MODEL_AHU)) {
+                else if (StringUtils.equals("StartStopCtl", param.getAbilityKey()) && StringUtils.equals(
+                    param.getModelCode(), METER_MODEL_AHU)) {
                     Map<String, String> ahuMapper = config.getAhuMapper();
                     String pointId = ahuMapper.get(String.format("%s.%s", param.getObjCode(), "setCtl-StartStop"));
                     Assert.notEmpty(pointId, -1, "该设备未配置控制测点pointId.");
-                    devAbilityCall(METER_MODEL_AHU, param.getObjCode(), pointId, param.getAbilityKey(), param.getAbilityParam());
+                    devAbilityCall(METER_MODEL_AHU, param.getObjCode(), pointId, param.getAbilityKey(),
+                        param.getAbilityParam());
                 }
-                else if (StringUtils.equals("OnOffCtl", param.getAbilityKey()) && StringUtils.equals(param.getModelCode(), METER_MODEL_AHU)) {
+                else if (StringUtils.equals("OnOffCtl", param.getAbilityKey()) && StringUtils.equals(
+                    param.getModelCode(), METER_MODEL_AHU)) {
                     Map<String, String> lightMapper = config.getLightMapper();
                     String pointId = lightMapper.get(String.format("%s.%s", param.getObjCode(), "setCtl-OnOff"));
                     Assert.notEmpty(pointId, -1, "该设备未配置控制测点pointId.");
-                    devAbilityCall(METER_MODEL_LIGHT, param.getObjCode(), pointId, param.getAbilityKey(), param.getAbilityParam());
+                    devAbilityCall(METER_MODEL_LIGHT, param.getObjCode(), pointId, param.getAbilityKey(),
+                        param.getAbilityParam());
                 }
 
                 callResponse = new CallResponse<>(0, "成功");
@@ -212,7 +215,8 @@ public class BaCtlHandler extends BaseMeterDevHandler {
     public void refreshOnline() {
     }
 
-    public void devAbilityCall(String modelCode, String deviceId, String pointId, String abilityKey, String paramValue) {
+    public void devAbilityCall(String modelCode, String deviceId, String pointId, String abilityKey,
+        String paramValue) {
         CodesVal codesVal = new CodesVal();
         codesVal.setPointId(pointId);
         codesVal.setValue(paramValue);
@@ -220,8 +224,8 @@ public class BaCtlHandler extends BaseMeterDevHandler {
         BaCtlEnergyTemplate template = new BaCtlEnergyTemplate(config.getUrl());
         CallData<String> callData = template.setCodesVal(new CodesValSetReq(codesVal));
 
-        saveCallLog(deviceId, modelCode, abilityKey, callData.getCallStatus(),
-            callData.getCallPayload(), callData.getResPayload());
+        saveCallLog(deviceId, modelCode, abilityKey, callData.getCallStatus(), callData.getCallPayload(),
+            callData.getResPayload());
     }
 
     private void meterReadingGw(String modeCode, String abilityKey, String objCode) {
@@ -399,9 +403,8 @@ public class BaCtlHandler extends BaseMeterDevHandler {
         Map<String, String> paramKeys = config.getXfMapper();
 
         Set<String> pointIds = paramKeys.entrySet().stream().filter(
-                entry -> StringUtils.startsWith(entry.getKey(), deviceCode)
-                    && !StringUtils.startsWith(entry.getKey(), deviceCode + ".setCtl-"))
-            .flatMap(entry -> Arrays.stream(StringUtils.split(entry.getValue(), ",")))
+                entry -> StringUtils.startsWith(entry.getKey(), deviceCode) && !StringUtils.startsWith(entry.getKey(),
+                    deviceCode + ".setCtl-")).flatMap(entry -> Arrays.stream(StringUtils.split(entry.getValue(), ",")))
             .map(String::trim).collect(Collectors.toSet());
 
         if (CollectionUtils.isNotEmpty(pointIds)) {
@@ -410,6 +413,8 @@ public class BaCtlHandler extends BaseMeterDevHandler {
             // 调用能耗数据接口获取实时数据
             CallData<String> callData = new BaCtlEnergyTemplate(config.getUrl()).getCodesVal(req);
             String callRes = callData.getResPayload();
+            saveCallLog(device.getDeviceCode(), device.getDeviceModel(), "SyncXfDevAttr", 0, JSON.toJSONString(req), callRes);
+
             JSONObject resJson = JSONObject.parseObject(callRes);
             Assert.isTrue(StringUtils.equals(resJson.getString("code"), "200"), resJson.getInteger("code"),
                 resJson.getString("error"));
@@ -422,28 +427,28 @@ public class BaCtlHandler extends BaseMeterDevHandler {
             Map<String, EmsObjAttrValue> dbMap = dbAttrList.stream()
                 .collect(Collectors.toMap(EmsObjAttrValue::getAttrKey, Function.identity()));
 
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "xfTemp", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "sfTemp", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "hfTemp", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "pfTemp", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "ppm", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "wCv", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "xfCv", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "pfCv", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "lwDpAlarm", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "fjUvAlarm", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "afAlarm", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "xfStatus", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "xfMA", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "xfFault", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "pfStatus", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "pfMA", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "pfFault", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "xfTempSetVal", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "LnSu", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "timeSetTag", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "manualTag", dbMap, retMap);
-            baDevTimeStatueCheckAndUpdate(METER_MODEL_XF, deviceCode, "timeStatus", dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "xfTemp", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "sfTemp", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "hfTemp", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "pfTemp", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "ppm", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "wCv", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "xfCv", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "pfCv", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "lwDpAlarm", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "fjUvAlarm", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "afAlarm", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "xfStatus", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "xfMA", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "xfFault", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "pfStatus", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "pfMA", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "pfFault", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "xfTempSetVal", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "LnSu", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "timeSetTag", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_XF, deviceCode, "manualTag", paramKeys, dbMap, retMap);
+            baDevTimeStatueCheckAndUpdate(METER_MODEL_XF, deviceCode, "timeStatus", paramKeys, dbMap, retMap);
         }
     }
 
@@ -451,11 +456,10 @@ public class BaCtlHandler extends BaseMeterDevHandler {
         String deviceCode = device.getDeviceCode();
         Map<String, String> paramKeys = config.getAhuMapper();
 
-        Set<String> pointIds = paramKeys.entrySet().stream()
-            .filter(entry -> StringUtils.startsWith(entry.getKey(), deviceCode)
-                && !StringUtils.startsWith(entry.getKey(), deviceCode + ".setCtl-"))
-            .flatMap(entry -> Arrays.stream(StringUtils.split(entry.getValue(), ","))).map(String::trim)
-            .collect(Collectors.toSet());
+        Set<String> pointIds = paramKeys.entrySet().stream().filter(
+                entry -> StringUtils.startsWith(entry.getKey(), deviceCode) && !StringUtils.startsWith(entry.getKey(),
+                    deviceCode + ".setCtl-")).flatMap(entry -> Arrays.stream(StringUtils.split(entry.getValue(), ",")))
+            .map(String::trim).collect(Collectors.toSet());
 
         if (CollectionUtils.isNotEmpty(pointIds)) {
             CodesValReq req = new CodesValReq(pointIds);
@@ -463,6 +467,7 @@ public class BaCtlHandler extends BaseMeterDevHandler {
             // 调用能耗数据接口获取实时数据
             CallData<String> callData = new BaCtlEnergyTemplate(config.getUrl()).getCodesVal(req);
             String callRes = callData.getResPayload();
+            saveCallLog(device.getDeviceCode(), device.getDeviceModel(), "SyncAuhDevAttr", 0, JSON.toJSONString(req), callRes);
             JSONObject resJson = JSONObject.parseObject(callRes);
             Assert.isTrue(StringUtils.equals(resJson.getString("code"), "200"), resJson.getInteger("code"),
                 resJson.getString("error"));
@@ -475,22 +480,22 @@ public class BaCtlHandler extends BaseMeterDevHandler {
             Map<String, EmsObjAttrValue> dbMap = dbAttrList.stream()
                 .collect(Collectors.toMap(EmsObjAttrValue::getAttrKey, Function.identity()));
 
-            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "xfTemp", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "sfTemp", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "hfTemp", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "wCv", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "xfCv", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "lwDpAlarm", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "fjUvAlarm", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "afAlarm", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "xfStatus", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "xfMA", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "xfFault", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "xfTempSetVal", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "LnSu", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "timeSetTag", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "manualTag", dbMap, retMap);
-            baDevTimeStatueCheckAndUpdate(METER_MODEL_AHU, deviceCode, "timeStatus", dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "xfTemp", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "sfTemp", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "hfTemp", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "wCv", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "xfCv", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "lwDpAlarm", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "fjUvAlarm", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "afAlarm", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "xfStatus", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "xfMA", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "xfFault", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "xfTempSetVal", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "LnSu", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "timeSetTag", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_AHU, deviceCode, "manualTag", paramKeys, dbMap, retMap);
+            baDevTimeStatueCheckAndUpdate(METER_MODEL_AHU, deviceCode, "timeStatus", paramKeys, dbMap, retMap);
         }
     }
 
@@ -509,6 +514,7 @@ public class BaCtlHandler extends BaseMeterDevHandler {
             // 调用能耗数据接口获取实时数据
             CallData<String> callData = new BaCtlEnergyTemplate(config.getUrl()).getCodesVal(req);
             String callRes = callData.getResPayload();
+            saveCallLog(device.getDeviceCode(), device.getDeviceModel(), "SyncWtDevAttr", 0, JSON.toJSONString(req), callRes);
             JSONObject resJson = JSONObject.parseObject(callRes);
             Assert.isTrue(StringUtils.equals(resJson.getString("code"), "200"), resJson.getInteger("code"),
                 resJson.getString("error"));
@@ -521,9 +527,9 @@ public class BaCtlHandler extends BaseMeterDevHandler {
             Map<String, EmsObjAttrValue> dbMap = dbAttrList.stream()
                 .collect(Collectors.toMap(EmsObjAttrValue::getAttrKey, Function.identity()));
 
-            baDevAttrCheckAndUpdate(METER_MODEL_WT, deviceCode, "autoState", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_WT, deviceCode, "runningState", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_WT, deviceCode, "faultState", dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_WT, deviceCode, "highLevelAlarm", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_WT, deviceCode, "lowLevelAlarm", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_WT, deviceCode, "tankLevel", paramKeys, dbMap, retMap);
         }
     }
 
@@ -542,6 +548,7 @@ public class BaCtlHandler extends BaseMeterDevHandler {
             // 调用能耗数据接口获取实时数据
             CallData<String> callData = new BaCtlEnergyTemplate(config.getUrl()).getCodesVal(req);
             String callRes = callData.getResPayload();
+            saveCallLog(device.getDeviceCode(), device.getDeviceModel(), "SyncWpDevAttr", 0, JSON.toJSONString(req), callRes);
             JSONObject resJson = JSONObject.parseObject(callRes);
             Assert.isTrue(StringUtils.equals(resJson.getString("code"), "200"), resJson.getInteger("code"),
                 resJson.getString("error"));
@@ -554,9 +561,9 @@ public class BaCtlHandler extends BaseMeterDevHandler {
             Map<String, EmsObjAttrValue> dbMap = dbAttrList.stream()
                 .collect(Collectors.toMap(EmsObjAttrValue::getAttrKey, Function.identity()));
 
-            baDevAttrCheckAndUpdate(METER_MODEL_WP, deviceCode, "autoState", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_WP, deviceCode, "runningState", dbMap, retMap);
-            baDevAttrCheckAndUpdate(METER_MODEL_WP, deviceCode, "faultState", dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_WP, deviceCode, "autoState", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_WP, deviceCode, "runningState", paramKeys, dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_WP, deviceCode, "faultState", paramKeys, dbMap, retMap);
         }
     }
 
@@ -564,11 +571,10 @@ public class BaCtlHandler extends BaseMeterDevHandler {
         String deviceCode = device.getDeviceCode();
         Map<String, String> paramKeys = config.getLightMapper();
 
-        Set<String> pointIds = paramKeys.entrySet().stream()
-            .filter(entry -> StringUtils.startsWith(entry.getKey(), deviceCode)
-                && !StringUtils.startsWith(entry.getKey(), deviceCode + ".setCtl-"))
-            .flatMap(entry -> Arrays.stream(StringUtils.split(entry.getValue(), ","))).map(String::trim)
-            .collect(Collectors.toSet());
+        Set<String> pointIds = paramKeys.entrySet().stream().filter(
+                entry -> StringUtils.startsWith(entry.getKey(), deviceCode) && !StringUtils.startsWith(entry.getKey(),
+                    deviceCode + ".setCtl-")).flatMap(entry -> Arrays.stream(StringUtils.split(entry.getValue(), ",")))
+            .map(String::trim).collect(Collectors.toSet());
 
         if (CollectionUtils.isNotEmpty(pointIds)) {
             CodesValReq req = new CodesValReq(pointIds);
@@ -576,6 +582,7 @@ public class BaCtlHandler extends BaseMeterDevHandler {
             // 调用能耗数据接口获取实时数据
             CallData<String> callData = new BaCtlEnergyTemplate(config.getUrl()).getCodesVal(req);
             String callRes = callData.getResPayload();
+            saveCallLog(device.getDeviceCode(), device.getDeviceModel(), "SyncLightDevAttr", 0, JSON.toJSONString(req), callRes);
             JSONObject resJson = JSONObject.parseObject(callRes);
             Assert.isTrue(StringUtils.equals(resJson.getString("code"), "200"), resJson.getInteger("code"),
                 resJson.getString("error"));
@@ -588,15 +595,14 @@ public class BaCtlHandler extends BaseMeterDevHandler {
             Map<String, EmsObjAttrValue> dbMap = dbAttrList.stream()
                 .collect(Collectors.toMap(EmsObjAttrValue::getAttrKey, Function.identity()));
 
-            baDevAttrCheckAndUpdate(METER_MODEL_LIGHT, deviceCode, "Switch", dbMap, retMap);
+            baDevAttrCheckAndUpdate(METER_MODEL_LIGHT, deviceCode, "Switch", paramKeys, dbMap, retMap);
         }
     }
 
     private void baDevAttrCheckAndUpdate(String devModel, String deviceCode, String attrKey,
-        Map<String, EmsObjAttrValue> dbAttrMap, Map<String, CodesVal> retMap) {
+        Map<String, String> kvMap, Map<String, EmsObjAttrValue> dbAttrMap, Map<String, CodesVal> retMap) {
         EmsObjAttrValue dbAttr = dbAttrMap.get(attrKey);
-        Map<String, String> keyParamMap = config.getXfMapper();
-        String pointId = keyParamMap.get(String.format("%s.%s", deviceCode, attrKey));
+        String pointId = kvMap.get(String.format("%s.%s", deviceCode, attrKey));
 
         if (null != dbAttr && retMap.containsKey(pointId)) {
             CodesVal codesVal = retMap.get(pointId);
@@ -615,9 +621,9 @@ public class BaCtlHandler extends BaseMeterDevHandler {
     }
 
     private void baDevTimeStatueCheckAndUpdate(String devModel, String deviceCode, String attrKey,
-        Map<String, EmsObjAttrValue> dbAttrMap, Map<String, CodesVal> retMap) {
+        Map<String, String> kvMap, Map<String, EmsObjAttrValue> dbAttrMap, Map<String, CodesVal> retMap) {
         EmsObjAttrValue dbAttr = dbAttrMap.get(attrKey);
-        String pointIdStr = config.getXfMapper().get(String.format("%s.%s", deviceCode, attrKey));
+        String pointIdStr = kvMap.get(String.format("%s.%s", deviceCode, attrKey));
 
         if (StringUtils.isNotEmpty(pointIdStr)) {
             String[] array = StringUtils.split(pointIdStr, ",");

+ 786 - 0
ems/ems-cloud/ems-dev-adapter/src/main/java/com/ruoyi/ems/handle/GrowattHandler.java

@@ -0,0 +1,786 @@
+/*
+ * 文 件 名:  GrowattHandler
+ * 版    权:  华设设计集团股份有限公司
+ * 描    述:  古瑞瓦特-光伏适配处理Handler
+ * 修 改 人:  lvwenbin
+ * 修改时间:  2025/12/18
+ * 跟踪单号:  <跟踪单号>
+ * 修改单号:  <修改单号>
+ * 修改内容:  完善采集器和逆变器数据同步功能
+ */
+package com.ruoyi.ems.handle;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.huashe.common.utils.DateUtils;
+import com.ruoyi.ems.config.GrowattConfig;
+import com.ruoyi.ems.core.GrowattTemplate;
+import com.ruoyi.ems.domain.EmsDevice;
+import com.ruoyi.ems.domain.EmsObjAttrValue;
+import com.ruoyi.ems.enums.DevObjType;
+import com.ruoyi.ems.enums.DevOnlineStatus;
+import com.ruoyi.ems.model.AbilityPayload;
+import com.ruoyi.ems.model.CallResponse;
+import com.ruoyi.ems.model.QueryDevice;
+import com.ruoyi.ems.model.growatt.DataLogger;
+import com.ruoyi.ems.model.growatt.DeviceInfo;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 古瑞瓦特-光伏适配处理Handler
+ * <功能详细描述>
+ *
+ * @author lvwenbin
+ * @version [版本号, 2025/12/18]
+ * @see [相关类/方法]
+ * @since [产品/模块版本]
+ */
+@Service
+public class GrowattHandler extends BaseDevHandler {
+    private static final Logger log = LoggerFactory.getLogger(GrowattHandler.class);
+
+    // 光伏系统模型代码
+    private static final String SYS_MODEL_CODE = "M_E5_SYS_PHOTOVOLTAIC";
+
+    // 光伏采集器模型代码
+    private static final String DEV_MODEL_COL = "M_W2_DEV_PHOTOVOLTAIC_COL";
+
+    // 光伏逆变器模型代码
+    private static final String DEV_MODEL_INVERTER = "M_E5_DEV_PHOTOVOLTAIC_INVERTER";
+
+    // 设备子系统代码
+    private static final String SUBSYSTEM_CODE = "SYS_GF";
+
+    // 逆变器设备类型(MAX类型)
+    private static final int INVERTER_TYPE_MAX = 18;
+
+    @Autowired
+    private GrowattConfig config;
+
+    @Override
+    public CallResponse<Void> call(AbilityPayload abilityParam) {
+        CallResponse<Void> callResponse = null;
+
+        try {
+            if (DevObjType.SYSTEM.getCode() == abilityParam.getObjType()) {
+                switch (abilityParam.getAbilityKey()) {
+                    case "SyncDevCollector":
+                        // 同步采集器数据
+                        CompletableFuture.runAsync(this::execSyncDevCollector);
+                        break;
+                    case "SyncDevInverter":
+                        // 同步逆变器列表数据
+                        CompletableFuture.runAsync(this::execSyncDevInverter);
+                        break;
+                    case "CollectInverterData":
+                        // 采集逆变器实时数据
+                        CompletableFuture.runAsync(this::execCollectInverterData);
+                        break;
+                    case "SyncAll":
+                        // 同步所有数据(采集器+逆变器+实时数据)
+                        CompletableFuture.runAsync(this::execSyncAll);
+                        break;
+                    default:
+                        throw new UnsupportedOperationException("不支持的abilityKey: " + abilityParam.getAbilityKey());
+                }
+            }
+            else if (DevObjType.DEVC.getCode() == abilityParam.getObjType()) {
+                if (StringUtils.equals(DEV_MODEL_COL, abilityParam.getModelCode())) {
+                    // 采集器设备能力
+                    switch (abilityParam.getAbilityKey()) {
+                        case "SyncAttr":
+                            execSyncCollectorAttr(abilityParam.getObjCode());
+                            break;
+                        default:
+                            throw new UnsupportedOperationException(
+                                "不支持的abilityKey: " + abilityParam.getAbilityKey());
+                    }
+                }
+                else if (StringUtils.equals(DEV_MODEL_INVERTER, abilityParam.getModelCode())) {
+                    // 逆变器设备能力
+                    switch (abilityParam.getAbilityKey()) {
+                        case "SyncAttr":
+                            execSyncInverterAttr(abilityParam.getObjCode());
+                            break;
+                        default:
+                            throw new UnsupportedOperationException(
+                                "不支持的abilityKey: " + abilityParam.getAbilityKey());
+                    }
+                }
+            }
+
+            callResponse = new CallResponse<>(0, "成功");
+        }
+        catch (Exception e) {
+            callResponse = new CallResponse<>(-1, e.getMessage());
+            log.error("调用ability异常", e);
+        }
+
+        return callResponse;
+    }
+
+    @Override
+    public List<EmsDevice> getDeviceList() {
+        QueryDevice queryDevice = new QueryDevice();
+        queryDevice.setDeviceModel(DEV_MODEL_INVERTER);
+        queryDevice.setSubsystemCode(SUBSYSTEM_CODE);
+        return deviceService.selectList(queryDevice);
+    }
+
+    @Override
+    public void refreshOnline() {
+        log.info("开始刷新光伏设备在线状态...");
+
+        try {
+            GrowattTemplate template = new GrowattTemplate(config.getUrl(), config.getToken());
+
+            // ==================== 第一步:刷新采集器在线状态 ====================
+            List<String> plantList = config.getPlantList();
+            if (CollectionUtils.isEmpty(plantList)) {
+                log.warn("未配置电站ID列表");
+                return;
+            }
+
+            // 从所有电站获取采集器列表
+            List<DataLogger> allDataLoggers = new ArrayList<>();
+            for (String plantId : plantList) {
+                List<DataLogger> dataLoggers = template.getDatalogList(plantId);
+                if (CollectionUtils.isNotEmpty(dataLoggers)) {
+                    allDataLoggers.addAll(dataLoggers);
+                }
+            }
+
+            if (CollectionUtils.isEmpty(allDataLoggers)) {
+                log.warn("API返回采集器列表为空");
+                return;
+            }
+
+            // 将API数据转为Map,key为sn
+            Map<String, DataLogger> apiDataMap = allDataLoggers.stream()
+                .collect(Collectors.toMap(DataLogger::getSn, Function.identity()));
+
+            // 查询本地采集器设备
+            QueryDevice queryCollector = new QueryDevice();
+            queryCollector.setDeviceModel(DEV_MODEL_COL);
+            queryCollector.setSubsystemCode(SUBSYSTEM_CODE);
+            List<EmsDevice> collectorDevices = deviceService.selectList(queryCollector);
+
+            // 采集器sn -> 在线状态 的映射(用于后续判断逆变器状态)
+            Map<String, Boolean> collectorOnlineMap = new HashMap<>();
+
+            for (EmsDevice device : collectorDevices) {
+                EmsObjAttrValue snAttr = objAttrValueService.selectObjAttrValue(DEV_MODEL_COL, device.getDeviceCode(),
+                    "sn");
+
+                if (snAttr == null || StringUtils.isBlank(snAttr.getAttrValue())) {
+                    continue;
+                }
+
+                String sn = snAttr.getAttrValue();
+                DataLogger apiData = apiDataMap.get(sn);
+
+                if (apiData == null) {
+                    continue;
+                }
+
+                // lost=false 表示在线,lost=true 表示离线
+                boolean isOnline = !apiData.isLost();
+                collectorOnlineMap.put(sn, isOnline);
+
+                int newStatus = isOnline ? DevOnlineStatus.ONLINE.getCode() : DevOnlineStatus.OFFLINE.getCode();
+                if (device.getDeviceStatus() == null || device.getDeviceStatus() != newStatus) {
+                    device.setDeviceStatus(newStatus);
+                    deviceService.updateEmsDevice(device);
+                    triggerEvent(device, isOnline ? "online" : "offline", null, new Date());
+                    log.info("采集器 {} 状态更新为 {}", device.getDeviceCode(), isOnline ? "在线" : "离线");
+                }
+            }
+
+            // ==================== 第二步:刷新逆变器在线状态 ====================
+            // 逆变器的在线状态由其关联的采集器决定
+            QueryDevice queryInverter = new QueryDevice();
+            queryInverter.setDeviceModel(DEV_MODEL_INVERTER);
+            queryInverter.setSubsystemCode(SUBSYSTEM_CODE);
+            List<EmsDevice> inverterDevices = deviceService.selectList(queryInverter);
+
+            for (EmsDevice device : inverterDevices) {
+                // 获取逆变器关联的采集器sn(dataloggerSn属性)
+                EmsObjAttrValue dataloggerSnAttr = objAttrValueService.selectObjAttrValue(DEV_MODEL_INVERTER,
+                    device.getDeviceCode(), "dataloggerSn");
+
+                if (dataloggerSnAttr == null || StringUtils.isBlank(dataloggerSnAttr.getAttrValue())) {
+                    continue;
+                }
+
+                String dataloggerSn = dataloggerSnAttr.getAttrValue();
+
+                // 根据关联的采集器状态判断逆变器状态
+                Boolean collectorOnline = collectorOnlineMap.get(dataloggerSn);
+                boolean isOnline = collectorOnline != null && collectorOnline;
+
+                int newStatus = isOnline ? DevOnlineStatus.ONLINE.getCode() : DevOnlineStatus.OFFLINE.getCode();
+                if (device.getDeviceStatus() == null || device.getDeviceStatus() != newStatus) {
+                    device.setDeviceStatus(newStatus);
+                    deviceService.updateEmsDevice(device);
+                    triggerEvent(device, isOnline ? "online" : "offline", null, new Date());
+                    log.info("逆变器 {} 状态更新为 {} (关联采集器:{})", device.getDeviceCode(),
+                        isOnline ? "在线" : "离线", dataloggerSn);
+                }
+            }
+
+            log.info("光伏设备在线状态刷新完成");
+
+        }
+        catch (Exception e) {
+            log.error("刷新光伏设备在线状态异常", e);
+        }
+    }
+
+    /**
+     * 同步所有数据
+     */
+    public void execSyncAll() {
+        log.info("开始同步光伏系统所有数据...");
+        execSyncDevCollector();
+        execSyncDevInverter();
+        execCollectInverterData();
+        log.info("光伏系统数据同步完成");
+    }
+
+    /**
+     * 同步采集器数据
+     * 调用API获取采集器列表,与本地数据库比对,更新状态和属性
+     */
+    public void execSyncDevCollector() {
+        log.info("开始同步采集器数据...");
+
+        try {
+            GrowattTemplate template = new GrowattTemplate(config.getUrl(), config.getToken());
+
+            // 1. 从API获取所有电站的采集器列表
+            List<DataLogger> allDataLoggers = new ArrayList<>();
+            List<String> plantList = config.getPlantList();
+            if (CollectionUtils.isEmpty(plantList)) {
+                log.warn("未配置电站ID列表");
+                return;
+            }
+
+            for (String plantId : plantList) {
+                List<DataLogger> dataLoggers = template.getDatalogList(plantId);
+                if (CollectionUtils.isNotEmpty(dataLoggers)) {
+                    allDataLoggers.addAll(dataLoggers);
+                }
+                log.info("从电站 {} 获取到 {} 个采集器", plantId, dataLoggers.size());
+            }
+
+            if (CollectionUtils.isEmpty(allDataLoggers)) {
+                log.warn("API返回采集器列表为空");
+                return;
+            }
+
+            log.info("从API共获取到 {} 个采集器", allDataLoggers.size());
+
+            // 将API数据转为Map,key为sn
+            Map<String, DataLogger> apiDataMap = allDataLoggers.stream()
+                .collect(Collectors.toMap(DataLogger::getSn, Function.identity(), (k1, k2) -> k1));
+
+            // 2. 查询本地数据库中的采集器设备
+            QueryDevice queryDevice = new QueryDevice();
+            queryDevice.setDeviceModel(DEV_MODEL_COL);
+            queryDevice.setSubsystemCode(SUBSYSTEM_CODE);
+            List<EmsDevice> localDevices = deviceService.selectList(queryDevice);
+            log.info("本地数据库有 {} 个采集器设备", localDevices.size());
+
+            if (CollectionUtils.isEmpty(localDevices)) {
+                log.warn("本地数据库无采集器设备");
+                return;
+            }
+
+            // 3. 遍历本地设备,通过sn属性与API数据匹配
+            for (EmsDevice device : localDevices) {
+                try {
+                    // 查询设备的sn属性
+                    EmsObjAttrValue snAttr = objAttrValueService.selectObjAttrValue(DEV_MODEL_COL,
+                        device.getDeviceCode(), "sn");
+
+                    if (snAttr == null || StringUtils.isBlank(snAttr.getAttrValue())) {
+                        log.warn("采集器设备 {} 无sn属性,跳过", device.getDeviceCode());
+                        continue;
+                    }
+
+                    String sn = snAttr.getAttrValue();
+                    DataLogger apiData = apiDataMap.get(sn);
+
+                    if (apiData == null) {
+                        log.warn("采集器 {} (sn={}) 在API中未找到", device.getDeviceCode(), sn);
+                        continue;
+                    }
+
+                    // 4. 更新设备属性
+                    List<EmsObjAttrValue> existingAttrs = objAttrValueService.selectByObjCode(DEV_MODEL_COL,
+                        device.getDeviceCode());
+                    Map<String, EmsObjAttrValue> attrMap = existingAttrs.stream()
+                        .collect(Collectors.toMap(EmsObjAttrValue::getAttrKey, Function.identity()));
+
+                    // 更新或插入属性值
+                    checkAndUpdate(attrMap, device.getDeviceCode(), DEV_MODEL_COL, "manufacturer",
+                        apiData.getManufacturer());
+                    checkAndUpdate(attrMap, device.getDeviceCode(), DEV_MODEL_COL, "model", apiData.getModel());
+                    checkAndUpdate(attrMap, device.getDeviceCode(), DEV_MODEL_COL, "netMode", apiData.getNetMode());
+                    checkAndUpdate(attrMap, device.getDeviceCode(), DEV_MODEL_COL, "type",
+                        String.valueOf(apiData.getType()));
+
+                    // lastUpdateTime 需要特殊处理
+                    if (apiData.getUpdateTime() != null) {
+                        String updateTimeStr = DateUtils.dateToString(apiData.getUpdateTime(), "yyyy-MM-dd HH:mm:ss");
+                        checkAndUpdate(attrMap, device.getDeviceCode(), DEV_MODEL_COL, "lastUpdateTime", updateTimeStr);
+                    }
+
+                    log.debug("采集器 {} 属性已更新", device.getDeviceCode());
+
+                }
+                catch (Exception e) {
+                    log.error("处理采集器设备 {} 异常", device.getDeviceCode(), e);
+                }
+            }
+
+            // 记录调用日志
+            saveCallLog(SUBSYSTEM_CODE, SYS_MODEL_CODE, "SyncDevCollector", 0,
+                "{\"plantList\":\"" + StringUtils.join(plantList, ",") + "\"}",
+                "{\"count\":" + allDataLoggers.size() + "}");
+
+            log.info("采集器数据同步完成");
+
+        }
+        catch (Exception e) {
+            log.error("同步采集器数据异常", e);
+            saveCallLog(SUBSYSTEM_CODE, SYS_MODEL_CODE, "SyncDevCollector", -1,
+                "{\"plantList\":\"" + StringUtils.join(config.getPlantList(), ",") + "\"}", e.getMessage());
+        }
+    }
+
+    /**
+     * 同步逆变器列表数据
+     * 调用API获取逆变器列表,与本地数据库比对,更新状态和属性
+     */
+    public void execSyncDevInverter() {
+        log.info("开始同步逆变器列表数据...");
+
+        try {
+            GrowattTemplate template = new GrowattTemplate(config.getUrl(), config.getToken());
+
+            // 1. 从API获取所有电站的设备列表
+            List<DeviceInfo> allDeviceList = new ArrayList<>();
+            List<String> plantList = config.getPlantList();
+            if (CollectionUtils.isEmpty(plantList)) {
+                log.warn("未配置电站ID列表");
+                return;
+            }
+
+            for (String plantId : plantList) {
+                List<DeviceInfo> deviceList = template.getDeviceList(plantId);
+                if (CollectionUtils.isNotEmpty(deviceList)) {
+                    allDeviceList.addAll(deviceList);
+                }
+                log.info("从电站 {} 获取到 {} 个设备", plantId, deviceList.size());
+            }
+
+            if (CollectionUtils.isEmpty(allDeviceList)) {
+                log.warn("API返回设备列表为空");
+                return;
+            }
+
+            log.info("从API共获取到 {} 个设备", allDeviceList.size());
+
+            // API返回的设备列表包含重复记录(type=1和type=4),需要去重
+            Map<String, DeviceInfo> apiDataMap = allDeviceList.stream().filter(info -> info.getType() == 1)
+                .collect(Collectors.toMap(DeviceInfo::getDeviceSn, Function.identity(), (k1, k2) -> k1));
+            log.info("过滤type=1后有 {} 个逆变器设备", apiDataMap.size());
+
+            // 2. 查询本地数据库中的逆变器设备
+            QueryDevice queryDevice = new QueryDevice();
+            queryDevice.setDeviceModel(DEV_MODEL_INVERTER);
+            queryDevice.setSubsystemCode(SUBSYSTEM_CODE);
+            List<EmsDevice> localDevices = deviceService.selectList(queryDevice);
+            log.info("本地数据库有 {} 个逆变器设备", localDevices.size());
+
+            if (CollectionUtils.isEmpty(localDevices)) {
+                log.warn("本地数据库无逆变器设备");
+                return;
+            }
+
+            // 3. 遍历本地设备,通过sn属性与API数据匹配
+            for (EmsDevice device : localDevices) {
+                try {
+                    // 查询设备的sn属性
+                    EmsObjAttrValue snAttr = objAttrValueService.selectObjAttrValue(DEV_MODEL_INVERTER,
+                        device.getDeviceCode(), "sn");
+
+                    if (snAttr == null || StringUtils.isBlank(snAttr.getAttrValue())) {
+                        log.warn("逆变器设备 {} 无sn属性,跳过", device.getDeviceCode());
+                        continue;
+                    }
+
+                    String sn = snAttr.getAttrValue();
+                    DeviceInfo apiData = apiDataMap.get(sn);
+
+                    if (apiData == null) {
+                        log.warn("逆变器 {} (sn={}) 在API中未找到", device.getDeviceCode(), sn);
+                        continue;
+                    }
+
+                    // 4. 更新设备属性
+                    List<EmsObjAttrValue> existingAttrs = objAttrValueService.selectByObjCode(DEV_MODEL_INVERTER,
+                        device.getDeviceCode());
+                    Map<String, EmsObjAttrValue> attrMap = existingAttrs.stream()
+                        .collect(Collectors.toMap(EmsObjAttrValue::getAttrKey, Function.identity(), (k1, k2) -> k1));
+
+                    // 更新或插入属性值
+                    checkAndUpdate(attrMap, device.getDeviceCode(), DEV_MODEL_INVERTER, "manufacturer",
+                        apiData.getManufacturer());
+                    checkAndUpdate(attrMap, device.getDeviceCode(), DEV_MODEL_INVERTER, "model", apiData.getModel());
+                    checkAndUpdate(attrMap, device.getDeviceCode(), DEV_MODEL_INVERTER, "type",
+                        String.valueOf(apiData.getType()));
+                    checkAndUpdate(attrMap, device.getDeviceCode(), DEV_MODEL_INVERTER, "status",
+                        String.valueOf(apiData.getStatus()));
+                    checkAndUpdate(attrMap, device.getDeviceCode(), DEV_MODEL_INVERTER, "lastUpdateTime",
+                        apiData.getLastUpdateTime());
+
+                    log.debug("逆变器 {} 属性已更新", device.getDeviceCode());
+
+                }
+                catch (Exception e) {
+                    log.error("处理逆变器设备 {} 异常", device.getDeviceCode(), e);
+                }
+            }
+
+            // 记录调用日志
+            saveCallLog(SUBSYSTEM_CODE, SYS_MODEL_CODE, "SyncDevInverter", 0,
+                "{\"plantList\":\"" + StringUtils.join(plantList, ",") + "\"}",
+                "{\"count\":" + apiDataMap.size() + "}");
+
+            log.info("逆变器列表数据同步完成");
+
+        }
+        catch (Exception e) {
+            log.error("同步逆变器列表数据异常", e);
+            saveCallLog(SUBSYSTEM_CODE, SYS_MODEL_CODE, "SyncDevInverter", -1,
+                "{\"plantList\":\"" + StringUtils.join(config.getPlantList(), ",") + "\"}", e.getMessage());
+        }
+    }
+
+    /**
+     * 采集逆变器实时数据
+     * 批量获取逆变器运行数据并更新到数据库
+     */
+    public void execCollectInverterData() {
+        log.info("开始采集逆变器实时数据...");
+
+        try {
+            // 1. 查询本地逆变器设备
+            QueryDevice queryDevice = new QueryDevice();
+            queryDevice.setDeviceModel(DEV_MODEL_INVERTER);
+            queryDevice.setSubsystemCode(SUBSYSTEM_CODE);
+            List<EmsDevice> localDevices = deviceService.selectList(queryDevice);
+
+            if (CollectionUtils.isEmpty(localDevices)) {
+                log.warn("本地数据库无逆变器设备");
+                return;
+            }
+
+            // 2. 获取所有逆变器的sn
+            Set<String> snSet = new HashSet<>();
+            Map<String, EmsDevice> snDeviceMap = new HashMap<>();
+
+            for (EmsDevice device : localDevices) {
+                EmsObjAttrValue snAttr = objAttrValueService.selectObjAttrValue(DEV_MODEL_INVERTER,
+                    device.getDeviceCode(), "sn");
+                if (snAttr != null && StringUtils.isNotBlank(snAttr.getAttrValue())) {
+                    snSet.add(snAttr.getAttrValue());
+                    snDeviceMap.put(snAttr.getAttrValue(), device);
+                }
+            }
+
+            if (snSet.isEmpty()) {
+                log.warn("没有可采集的逆变器sn");
+                return;
+            }
+
+            log.info("准备采集 {} 个逆变器的实时数据", snSet.size());
+
+            // 3. 调用API批量获取设备数据
+            GrowattTemplate template = new GrowattTemplate(config.getUrl(), config.getToken());
+            List<String> snList = new ArrayList<>(snSet);
+            JSONObject deviceDataJson = template.getDeviceData(INVERTER_TYPE_MAX, snList);
+
+            if (deviceDataJson == null || deviceDataJson.isEmpty()) {
+                log.warn("API返回设备数据为空");
+                return;
+            }
+
+            log.info("从API获取到 {} 个设备的实时数据", deviceDataJson.size());
+
+            // 4. 解析并更新每个设备的数据
+            deviceDataJson.forEach((sn, dataObj) -> {
+                EmsDevice device = snDeviceMap.get(sn);
+
+                if (device != null) {
+                    try {
+                        JSONObject data = (JSONObject) dataObj;
+                        updateInverterRuntimeData(device, data);
+                        log.debug("逆变器 {} 实时数据已更新", device.getDeviceCode());
+                    }
+                    catch (Exception e) {
+                        log.error("更新逆变器 {} 实时数据异常", device.getDeviceCode(), e);
+                    }
+                }
+                else {
+                    log.warn("sn={} 未找到对应设备", sn);
+                }
+            });
+
+            // 记录调用日志
+            saveCallLog(SUBSYSTEM_CODE, SYS_MODEL_CODE, "CollectInverterData", 0, "{\"snCount\":" + snSet.size() + "}",
+                "{\"dataCount\":" + deviceDataJson.size() + "}");
+
+            log.info("逆变器实时数据采集完成");
+
+        }
+        catch (Exception e) {
+            log.error("采集逆变器实时数据异常", e);
+            saveCallLog(SUBSYSTEM_CODE, SYS_MODEL_CODE, "CollectInverterData", -1, null, e.getMessage());
+        }
+    }
+
+    /**
+     * 更新逆变器运行时数据
+     *
+     * @param device 设备
+     * @param data   API返回的数据
+     */
+    private void updateInverterRuntimeData(EmsDevice device, JSONObject data) {
+        // 获取现有属性
+        List<EmsObjAttrValue> existingAttrs = objAttrValueService.selectByObjCode(DEV_MODEL_INVERTER,
+            device.getDeviceCode());
+        Map<String, EmsObjAttrValue> attrMap = existingAttrs.stream()
+            .collect(Collectors.toMap(EmsObjAttrValue::getAttrKey, Function.identity()));
+
+        String deviceCode = device.getDeviceCode();
+
+        // 更新设备状态属性
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "statusText", data.getString("statusText"));
+
+        // === 功率相关 ===
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "pac", formatDouble(data.getDouble("pac")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "ppv", formatDouble(data.getDouble("ppv")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "ppv1", formatDouble(data.getDouble("ppv1")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "ppv2", formatDouble(data.getDouble("ppv2")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "ppv3", formatDouble(data.getDouble("ppv3")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "ppv4", formatDouble(data.getDouble("ppv4")));
+
+        // === 电压相关 (PV输入电压) ===
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "vpv1", formatDouble(data.getDouble("vpv1")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "vpv2", formatDouble(data.getDouble("vpv2")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "vpv3", formatDouble(data.getDouble("vpv3")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "vpv4", formatDouble(data.getDouble("vpv4")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "vpv5", formatDouble(data.getDouble("vpv5")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "vpv6", formatDouble(data.getDouble("vpv6")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "vpv7", formatDouble(data.getDouble("vpv7")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "vpv8", formatDouble(data.getDouble("vpv8")));
+
+        // === 组串电压 (vString) ===
+        for (int i = 1; i <= 16; i++) {
+            String key = "vString" + i;
+            Double value = data.getDouble(key);
+            if (value != null && value != 0.0) {
+                checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, key, formatDouble(value));
+            }
+        }
+
+        // === 母线电压 ===
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "pBusVoltage",
+            formatDouble(data.getDouble("pBusVoltage")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "nBusVoltage",
+            formatDouble(data.getDouble("nBusVoltage")));
+
+        // === 交流输出电压 ===
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "vacr", formatDouble(data.getDouble("vacr")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "vacs", formatDouble(data.getDouble("vacs")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "vact", formatDouble(data.getDouble("vact")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "vacRs", formatDouble(data.getDouble("vacRs")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "vacSt", formatDouble(data.getDouble("vacSt")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "vacTr", formatDouble(data.getDouble("vacTr")));
+
+        // === 温度相关 ===
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "temperature",
+            formatDouble(data.getDouble("temperature")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "temperature2",
+            formatDouble(data.getDouble("temperature2")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "temperature3",
+            formatDouble(data.getDouble("temperature3")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "temperature5",
+            formatDouble(data.getDouble("temperature5")));
+
+        // === 发电量相关 ===
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "eacToday", formatDouble(data.getDouble("eacToday")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "eacTotal", formatDouble(data.getDouble("eacTotal")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "epvTotal", formatDouble(data.getDouble("epvTotal")));
+
+        // === 频率 ===
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "fac", formatDouble(data.getDouble("fac")));
+
+        // === 功率因数 ===
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "pf", formatDouble(data.getDouble("pf")));
+
+        // === 故障相关 ===
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "faultCode1",
+            String.valueOf(data.getIntValue("faultCode1")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "faultCode2",
+            String.valueOf(data.getIntValue("faultCode2")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "faultType",
+            String.valueOf(data.getIntValue("faultType")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "faultValue",
+            String.valueOf(data.getIntValue("faultValue")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "warnCode",
+            String.valueOf(data.getIntValue("warnCode")));
+
+        // === 其他运行参数 ===
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "deratingMode",
+            String.valueOf(data.getIntValue("deratingMode")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "gfci", String.valueOf(data.getIntValue("gfci")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "pvIso", formatDouble(data.getDouble("pvIso")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "pidBus", formatDouble(data.getDouble("pidBus")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "opFullwatt",
+            formatDouble(data.getDouble("opFullwatt")));
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "timeTotal", formatDouble(data.getDouble("timeTotal")));
+
+        // === 更新时间 ===
+        checkAndUpdate(attrMap, deviceCode, DEV_MODEL_INVERTER, "time", data.getString("time"));
+    }
+
+    /**
+     * 格式化Double值,保留2位小数
+     */
+    private String formatDouble(Double value) {
+        if (value == null) {
+            return "0";
+        }
+        return String.format("%.2f", value);
+    }
+
+    /**
+     * 同步单个采集器属性
+     */
+    private void execSyncCollectorAttr(String objCode) {
+        log.info("同步采集器 {} 属性", objCode);
+
+        try {
+            // 获取设备sn
+            EmsObjAttrValue snAttr = objAttrValueService.selectObjAttrValue(DEV_MODEL_COL, objCode, "sn");
+            if (snAttr == null || StringUtils.isBlank(snAttr.getAttrValue())) {
+                log.warn("采集器 {} 无sn属性", objCode);
+                return;
+            }
+
+            GrowattTemplate template = new GrowattTemplate(config.getUrl(), config.getToken());
+
+            // 从所有电站获取采集器列表
+            List<DataLogger> allDataLoggers = new ArrayList<>();
+            List<String> plantList = config.getPlantList();
+            for (String plantId : plantList) {
+                List<DataLogger> dataLoggers = template.getDatalogList(plantId);
+                if (CollectionUtils.isNotEmpty(dataLoggers)) {
+                    allDataLoggers.addAll(dataLoggers);
+                }
+            }
+
+            String sn = snAttr.getAttrValue();
+            DataLogger target = allDataLoggers.stream().filter(d -> sn.equals(d.getSn())).findFirst().orElse(null);
+
+            if (target == null) {
+                log.warn("采集器 sn={} 在API中未找到", sn);
+                return;
+            }
+
+            // 更新属性
+            List<EmsObjAttrValue> existingAttrs = objAttrValueService.selectByObjCode(DEV_MODEL_COL, objCode);
+            Map<String, EmsObjAttrValue> attrMap = existingAttrs.stream()
+                .collect(Collectors.toMap(EmsObjAttrValue::getAttrKey, Function.identity(), (k1, k2) -> k1));
+
+            checkAndUpdate(attrMap, objCode, DEV_MODEL_COL, "manufacturer", target.getManufacturer());
+            checkAndUpdate(attrMap, objCode, DEV_MODEL_COL, "model", target.getModel());
+            checkAndUpdate(attrMap, objCode, DEV_MODEL_COL, "netMode", target.getNetMode());
+            checkAndUpdate(attrMap, objCode, DEV_MODEL_COL, "type", String.valueOf(target.getType()));
+
+            log.info("采集器 {} 属性同步完成", objCode);
+
+        }
+        catch (Exception e) {
+            log.error("同步采集器 {} 属性异常", objCode, e);
+        }
+    }
+
+    /**
+     * 同步单个逆变器属性
+     */
+    private void execSyncInverterAttr(String objCode) {
+        log.info("同步逆变器 {} 属性", objCode);
+
+        try {
+            // 获取设备sn
+            EmsObjAttrValue snAttr = objAttrValueService.selectObjAttrValue(DEV_MODEL_INVERTER, objCode, "sn");
+            if (snAttr == null || StringUtils.isBlank(snAttr.getAttrValue())) {
+                log.warn("逆变器 {} 无sn属性", objCode);
+                return;
+            }
+
+            String sn = snAttr.getAttrValue();
+
+            // 调用API获取实时数据
+            GrowattTemplate template = new GrowattTemplate(config.getUrl(), config.getToken());
+            Map<String, Object> deviceDataMap = template.getDeviceData(INVERTER_TYPE_MAX,
+                Collections.singletonList(sn));
+
+            if (deviceDataMap == null || !deviceDataMap.containsKey(sn)) {
+                log.warn("逆变器 sn={} 在API中未找到实时数据", sn);
+                return;
+            }
+
+            // 查询设备
+            QueryDevice query = new QueryDevice();
+            query.setDeviceModel(DEV_MODEL_INVERTER);
+            query.setDeviceCode(objCode);
+            List<EmsDevice> devices = deviceService.selectList(query);
+
+            if (CollectionUtils.isEmpty(devices)) {
+                log.warn("逆变器设备 {} 不存在", objCode);
+                return;
+            }
+
+            JSONObject data = (JSONObject) deviceDataMap.get(sn);
+            updateInverterRuntimeData(devices.get(0), data);
+
+            log.info("逆变器 {} 属性同步完成", objCode);
+
+        }
+        catch (Exception e) {
+            log.error("同步逆变器 {} 属性异常", objCode, e);
+        }
+    }
+}

+ 1 - 1
ems/ems-cloud/ems-dev-adapter/src/main/java/com/ruoyi/ems/model/growatt/DataLogger.java

@@ -37,7 +37,7 @@ public class DataLogger {
     @JSONField(name = "last_update_time")
     private JSONObject updateTime;
 
-    private Date getUpdateTime() {
+    public Date getUpdateTime() {
         return new Date(updateTime.getLongValue("time"));
     }
 }

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

@@ -61,6 +61,28 @@ adapter:
     readTimeout: 500
     writeTimeout: 500
     notifyEnabled: true
+  # 充电桩Socket服务
+  charging-pile:
+    server:
+      host: 127.0.0.1
+      port: 9310
+    ## 线程池配置
+    executor:
+      bossGroup:
+        corePoolSize: 5
+        maxPoolSize: 5
+        queueCapacity: 100
+        namePrefix: 'bossGroup-'
+      workerGroup:
+        corePoolSize: 5
+        maxPoolSize: 5
+        queueCapacity: 100
+        namePrefix: 'workerGroup-'
+      msgExec:
+        corePoolSize: 5
+        maxPoolSize: 5
+        queueCapacity: 1000
+        namePrefix: 'msgExec-'
   # 安科瑞
   acrel:
     url: http://127.0.0.1:8090
@@ -367,69 +389,69 @@ adapter:
     lightMapper:
       'Z020-B-LIGHT-01':
         setCtl-OnOff: 'C_8001_BV_0000'
-        Switch: 'C_8001_BO_0000'
+        Switch: 'C_8001_DO_0000'
       'Z020-B-LIGHT-02':
         setCtl-OnOff: 'C_8001_BV_0002'
-        Switch: 'C_8002_BO_0001'
+        Switch: 'C_8002_DO_0001'
       'Z020-B-LIGHT-03':
         setCtl-OnOff: 'C_8001_BV_0008'
-        Switch: 'C_8001_BO_0001'
+        Switch: 'C_8001_DO_0001'
       'Z020-B-LIGHT-04':
         setCtl-OnOff: 'C_8001_BV_0002'
-        Switch: 'C_8001_BO_0004'
+        Switch: 'C_8001_DO_0004'
       'Z020-B-LIGHT-05':
         setCtl-OnOff: 'C_8001_BV_0000'
-        Switch: 'C_8001_BO_0001'
+        Switch: 'C_8001_DO_0001'
       'Z020-B-LIGHT-06':
         setCtl-OnOff: 'C_8001_BV_0018'
-        Switch: 'C_8001_BO_0005'
+        Switch: 'C_8001_DO_0005'
       'Z020-B-LIGHT-07':
         setCtl-OnOff: 'C_8001_BV_0020'
-        Switch: 'C_8001_BO_0006'
+        Switch: 'C_8001_DO_0006'
       'Z020-B-LIGHT-08':
-        Switch: 'C_8001_BO_0007'
+        Switch: 'C_8001_DO_0007'
       'Z020-B-LIGHT-09':
         setCtl-OnOff: 'C_8001_BV_0022'
-        Switch: 'C_8002_BO_0000'
+        Switch: 'C_8002_DO_0000'
       'Z020-B-LIGHT-10':
         setCtl-OnOff: 'C_8001_BV_0024'
-        Switch: 'C_8002_BO_0002'
+        Switch: 'C_8002_DO_0002'
       'Z020-B-LIGHT-11':
         setCtl-OnOff: 'C_8001_BV_0028'
-        Switch: 'C_8001_BO_0003'
+        Switch: 'C_8001_DO_0003'
       'Z020-N-LIGHT-01':
         setCtl-OnOff: 'C_7001_BV_0000'
-        Switch: 'C_7001_BO_0000'
+        Switch: 'C_7001_DO_0000'
       'Z020-N-LIGHT-02':
         setCtl-OnOff: 'C_7001_BV_0002'
-        Switch: 'C_7001_BO_0001'
+        Switch: 'C_7001_DO_0001'
       'Z020-N-LIGHT-03':
         setCtl-OnOff: 'C_7001_BV_0004'
-        Switch: 'C_7001_BO_0002'
+        Switch: 'C_7001_DO_0002'
       'Z020-N-LIGHT-04':
         setCtl-OnOff: 'C_7001_BV_0012'
-        Switch: 'C_7001_BO_0004'
+        Switch: 'C_7001_DO_0004'
       'Z020-N-LIGHT-05':
         setCtl-OnOff: 'C_7001_BV_0010'
-        Switch: 'C_7001_BO_0003'
+        Switch: 'C_7001_DO_0003'
       'Z020-N-LIGHT-06':
         setCtl-OnOff: 'C_7001_BV_0018'
-        Switch: 'C_7001_BO_0006'
+        Switch: 'C_7001_DO_0006'
       'Z020-N-LIGHT-07':
         setCtl-OnOff: 'C_7001_BV_0020'
-        Switch: 'C_7001_BO_0007'
+        Switch: 'C_7001_DO_0007'
       'Z020-N-LIGHT-08':
         setCtl-OnOff: 'C_7001_BV_0022'
-        Switch: 'C_7002_BO_0000'
+        Switch: 'C_7002_DO_0000'
       'Z020-N-LIGHT-09':
         setCtl-OnOff: 'C_7001_BV_0022'
-        Switch: 'C_7002_BO_0001'
+        Switch: 'C_7002_DO_0001'
       'Z020-N-LIGHT-10':
         setCtl-OnOff: 'C_7001_BV_0024'
-        Switch: 'C_7002_BO_0004'
+        Switch: 'C_7002_DO_0004'
       'Z020-N-LIGHT-11':
         setCtl-OnOff: 'C_7001_BV_0028'
-        Switch: 'C_7001_BO_0005'
+        Switch: 'C_7001_DO_0005'
 # mybatis配置
 mybatis:
   # 搜索指定包别名

+ 26 - 22
ems/ems-cloud/ems-dev-adapter/src/main/resources/application-prod-ct.yml

@@ -61,6 +61,10 @@ adapter:
     readTimeout: 500
     writeTimeout: 500
     notifyEnabled: true
+  # 充电桩Socket服务
+  charging-pile:
+    host: 127.0.0.1
+    port: 9310
   # 安科瑞
   acrel:
     url: http://172.61.55.66:8090
@@ -367,69 +371,69 @@ adapter:
     lightMapper:
       'Z020-B-LIGHT-01':
         setCtl-OnOff: 'C_8001_BV_0000'
-        Switch: 'C_8001_BO_0000'
+        Switch: 'C_8001_DO_0000'
       'Z020-B-LIGHT-02':
         setCtl-OnOff: 'C_8001_BV_0002'
-        Switch: 'C_8002_BO_0001'
+        Switch: 'C_8002_DO_0001'
       'Z020-B-LIGHT-03':
         setCtl-OnOff: 'C_8001_BV_0008'
-        Switch: 'C_8001_BO_0001'
+        Switch: 'C_8001_DO_0001'
       'Z020-B-LIGHT-04':
         setCtl-OnOff: 'C_8001_BV_0002'
-        Switch: 'C_8001_BO_0004'
+        Switch: 'C_8001_DO_0004'
       'Z020-B-LIGHT-05':
         setCtl-OnOff: 'C_8001_BV_0000'
-        Switch: 'C_8001_BO_0001'
+        Switch: 'C_8001_DO_0001'
       'Z020-B-LIGHT-06':
         setCtl-OnOff: 'C_8001_BV_0018'
-        Switch: 'C_8001_BO_0005'
+        Switch: 'C_8001_DO_0005'
       'Z020-B-LIGHT-07':
         setCtl-OnOff: 'C_8001_BV_0020'
-        Switch: 'C_8001_BO_0006'
+        Switch: 'C_8001_DO_0006'
       'Z020-B-LIGHT-08':
-        Switch: 'C_8001_BO_0007'
+        Switch: 'C_8001_DO_0007'
       'Z020-B-LIGHT-09':
         setCtl-OnOff: 'C_8001_BV_0022'
-        Switch: 'C_8002_BO_0000'
+        Switch: 'C_8002_DO_0000'
       'Z020-B-LIGHT-10':
         setCtl-OnOff: 'C_8001_BV_0024'
-        Switch: 'C_8002_BO_0002'
+        Switch: 'C_8002_DO_0002'
       'Z020-B-LIGHT-11':
         setCtl-OnOff: 'C_8001_BV_0028'
-        Switch: 'C_8001_BO_0003'
+        Switch: 'C_8001_DO_0003'
       'Z020-N-LIGHT-01':
         setCtl-OnOff: 'C_7001_BV_0000'
-        Switch: 'C_7001_BO_0000'
+        Switch: 'C_7001_DO_0000'
       'Z020-N-LIGHT-02':
         setCtl-OnOff: 'C_7001_BV_0002'
-        Switch: 'C_7001_BO_0001'
+        Switch: 'C_7001_DO_0001'
       'Z020-N-LIGHT-03':
         setCtl-OnOff: 'C_7001_BV_0004'
-        Switch: 'C_7001_BO_0002'
+        Switch: 'C_7001_DO_0002'
       'Z020-N-LIGHT-04':
         setCtl-OnOff: 'C_7001_BV_0012'
-        Switch: 'C_7001_BO_0004'
+        Switch: 'C_7001_DO_0004'
       'Z020-N-LIGHT-05':
         setCtl-OnOff: 'C_7001_BV_0010'
-        Switch: 'C_7001_BO_0003'
+        Switch: 'C_7001_DO_0003'
       'Z020-N-LIGHT-06':
         setCtl-OnOff: 'C_7001_BV_0018'
-        Switch: 'C_7001_BO_0006'
+        Switch: 'C_7001_DO_0006'
       'Z020-N-LIGHT-07':
         setCtl-OnOff: 'C_7001_BV_0020'
-        Switch: 'C_7001_BO_0007'
+        Switch: 'C_7001_DO_0007'
       'Z020-N-LIGHT-08':
         setCtl-OnOff: 'C_7001_BV_0022'
-        Switch: 'C_7002_BO_0000'
+        Switch: 'C_7002_DO_0000'
       'Z020-N-LIGHT-09':
         setCtl-OnOff: 'C_7001_BV_0022'
-        Switch: 'C_7002_BO_0001'
+        Switch: 'C_7002_DO_0001'
       'Z020-N-LIGHT-10':
         setCtl-OnOff: 'C_7001_BV_0024'
-        Switch: 'C_7002_BO_0004'
+        Switch: 'C_7002_DO_0004'
       'Z020-N-LIGHT-11':
         setCtl-OnOff: 'C_7001_BV_0028'
-        Switch: 'C_7001_BO_0005'
+        Switch: 'C_7001_DO_0005'
 # mybatis配置
 mybatis:
   # 搜索指定包别名

Разница между файлами не показана из-за своего большого размера
+ 1 - 0
ems/ems-cloud/ems-dev-adapter/src/test/java/com/huashe/test/GrowattTest.java


+ 54 - 28
ems/ems-core/src/main/resources/mapper/ems/EmsObjAbilityCallLogMapper.xml

@@ -20,29 +20,55 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <sql id="selectList">
-        select l.id, l.obj_code,
-               CASE
-                   WHEN m.obj_type = 2 THEN d.device_name
-                   WHEN m.obj_type = 3 THEN s.system_name
-                   END as obj_name,
-               l.model_code, m.model_name, l.ability_key, a.ability_name, l.call_time, l.call_status from adm_ems_obj_ability_call_log l
-        left join adm_ems_obj_model m on l.model_code = m.model_code
-        left join adm_ems_device d on l.obj_code = d.device_code and m.obj_type = 2
-        left join adm_ems_subsystem s on l.obj_code = s.system_code and m.obj_type = 3
-        left join adm_ems_obj_ability a on l.model_code = a.model_code and l.ability_key = a.ability_key
+        SELECT
+            l.id,
+            l.obj_code,
+            CASE
+                WHEN m.obj_type = 2 THEN d.device_name
+                WHEN m.obj_type = 3 THEN s.system_name
+                END as obj_name,
+            l.model_code,
+            m.model_name,
+            l.ability_key,
+            a.ability_name,
+            l.call_time,
+            l.call_status
+        FROM adm_ems_obj_ability_call_log l
+                 INNER JOIN adm_ems_obj_model m
+                            ON l.model_code = m.model_code
+                 LEFT JOIN adm_ems_device d
+                           ON m.obj_type = 2 AND l.obj_code = d.device_code
+                 LEFT JOIN adm_ems_subsystem s
+                           ON m.obj_type = 3 AND l.obj_code = s.system_code
+                 LEFT JOIN adm_ems_obj_ability a
+                           ON l.model_code = a.model_code
+                               AND l.ability_key = a.ability_key
     </sql>
 
     <sql id="selectDetail">
-        select l.id, l.obj_code,
-               case
-                   WHEN m.obj_type = 2 THEN d.device_name
-                   WHEN m.obj_type = 3 THEN s.system_name
-                   END as obj_name,
-               l.model_code, m.model_name, l.ability_key, a.ability_name, l.call_time, l.call_status, l.call_payload, l.res_time, l.res_payload from adm_ems_obj_ability_call_log l
-        left join adm_ems_obj_model m on l.model_code = m.model_code
-        left join adm_ems_device d on l.obj_code = d.device_code and m.obj_type = 2
-        left join adm_ems_subsystem s on l.obj_code = s.system_code and m.obj_type = 3
-        left join adm_ems_obj_ability a on l.model_code = a.model_code and l.ability_key = a.ability_key
+        SELECT
+            l.id,
+            l.obj_code,
+            CASE
+                WHEN m.obj_type = 2 THEN d.device_name
+                WHEN m.obj_type = 3 THEN s.system_name
+                END as obj_name,
+            l.model_code,
+            m.model_name,
+            l.ability_key,
+            a.ability_name,
+            l.call_time,
+            l.call_status, l.call_payload, l.res_time, l.res_payload
+        FROM adm_ems_obj_ability_call_log l
+                 INNER JOIN adm_ems_obj_model m
+                            ON l.model_code = m.model_code
+                 LEFT JOIN adm_ems_device d
+                           ON m.obj_type = 2 AND l.obj_code = d.device_code
+                 LEFT JOIN adm_ems_subsystem s
+                           ON m.obj_type = 3 AND l.obj_code = s.system_code
+                 LEFT JOIN adm_ems_obj_ability a
+                           ON l.model_code = a.model_code
+                               AND l.ability_key = a.ability_key
     </sql>
 
     <select id="selectObjAbilityCallLogById" parameterType="java.lang.Long" resultMap="objAbilityCallLogResult">
@@ -52,14 +78,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <select id="selectObjAbilityCallLog" parameterType="com.ruoyi.ems.domain.EmsObjAbilityCallLog" resultMap="objAbilityCallLogResult">
         <include refid="selectList"/>
-        <where>  
-            <if test="objCode != null  and objCode != ''"> and l.obj_code = #{objCode}</if>
-            <if test="modelCode != null  and modelCode != ''"> and l.model_code = #{modelCode}</if>
-            <if test="abilityKey != null  and abilityKey != ''"> and l.ability_key = #{abilityKey}</if>
-            <if test="callStatus != null "> and l.call_status = #{callStatus}</if>
-            <if test="startRecTime != null  and startRecTime != '' and endRecTime != null and endRecTime !=''">
-                and l.call_time between #{startRecTime} and #{endRecTime}
-            </if>
+        <where>
             <if test="modelCodes != null">and l.model_code in
                 (
                 <foreach collection="modelCodes" item="item" index="index" separator=",">
@@ -67,6 +86,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 </foreach>
                 )
             </if>
+            <if test="modelCode != null  and modelCode != ''"> and l.model_code = #{modelCode}</if>
+            <if test="startRecTime != null  and startRecTime != '' and endRecTime != null and endRecTime !=''">
+                and l.call_time between #{startRecTime} and #{endRecTime}
+            </if>
+            <if test="objCode != null  and objCode != ''"> and l.obj_code = #{objCode}</if>
+            <if test="abilityKey != null  and abilityKey != ''"> and l.ability_key = #{abilityKey}</if>
+            <if test="callStatus != null "> and l.call_status = #{callStatus}</if>
         </where>
     </select>
 

+ 219 - 5
ems/sql/ems_init_data_ctfwq.sql

@@ -23,9 +23,6 @@ INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `s
 INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `short_name`, `desc`, `order_num`, `status`) VALUES ('321283124S300260', '321283124S3002', '0,321283124S3002', '南区储能', '储能', '南区储能', 6, 0);
 INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `short_name`, `desc`, `order_num`, `status`) VALUES ('321283124S300270', '321283124S3002', '0,321283124S3002', '南区充电桩', '充电桩', '南区充电桩', 7, 0);
 
-INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `short_name`, `desc`, `order_num`, `status`) VALUES ('S30K140-S30K150', '321283124S3003', '0,321283124S3003', '桩号段S30K140-S30K150', '桩号段S30K140-S30K150', '区段S30K140+300-S30K150+200', 1, 0);
-INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `short_name`, `desc`, `order_num`, `status`) VALUES ('S30K150-S30K180', '321283124S3003', '0,321283124S3003', '桩号段S30K140-S30K150', '桩号段S30K140-S30K150', '区段S30K150+300-S30K180+300', 2, 0);
-
 -- 区块
 INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `short_name`, `desc`, `order_num`, `status`) VALUES ('321283124S30010101', '321283124S300101', '0,321283124S3001,321283124S300101', '一楼', '一楼', '综合楼一楼', 1, 0);
 INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `short_name`, `desc`, `order_num`, `status`) VALUES ('321283124S30010102', '321283124S300101', '0,321283124S3001,321283124S300101', '商铺', '商铺', '综合楼商铺', 2, 0);
@@ -71,6 +68,14 @@ INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `s
 INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `short_name`, `desc`, `order_num`, `status`) VALUES ('321283124S30020201', '321283124S300202', '0,321283124S3002,321283124S300202', '南区司机之家维修间', '南区司机之家维修间', '南区司机之家维修间', 1, 0);
 INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `short_name`, `desc`, `order_num`, `status`) VALUES ('321283124S30020202', '321283124S300202', '0,321283124S3002,321283124S300202', '南区司机之家二楼', '南区司机之家二楼', '南区司机之家二楼', 2, 0);
 
+INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `short_name`, `desc`, `order_num`, `status`) VALUES ('321283124S30015001', '321283124S300150', '0,321283124S300150', '服务区北区主楼屋顶', '北区主楼屋顶', '北区主楼屋顶-光伏', 1, 0);
+INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `short_name`, `desc`, `order_num`, `status`) VALUES ('321283124S30015002', '321283124S300150', '0,321283124S300150', '服务区北区配电房屋顶', '北区配电房屋顶', '服务区北区配电房-光伏', 2, 0);
+INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `short_name`, `desc`, `order_num`, `status`) VALUES ('321283124S30015003', '321283124S300150', '0,321283124S300150', '服务区北区车棚', '北区车棚', '服务区北区车棚-光伏', 3, 0);
+INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `short_name`, `desc`, `order_num`, `status`) VALUES ('321283124S30025001', '321283124S300250', '0,321283124S300250', '服务区南区主楼屋顶', '南区主楼屋顶', '北区主楼屋顶-光伏', 1, 0);
+INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `short_name`, `desc`, `order_num`, `status`) VALUES ('321283124S30025002', '321283124S300250', '0,321283124S300250', '服务区南区配电房屋顶', '南区配电房屋顶', '服务区北区配电房-光伏', 2, 0);
+INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `short_name`, `desc`, `order_num`, `status`) VALUES ('321283124S30025003', '321283124S300250', '0,321283124S300250', '服务区南区车棚', '南区车棚', '服务区北区车棚-光伏', 3, 0);
+INSERT INTO `adm_area` (`area_code`, `parent_code`, `ancestors`, `area_name`, `short_name`, `desc`, `order_num`, `status`) VALUES ('321283124S30025004', '321283124S300250', '0,321283124S300250', '服务区南区办公室', '南区办公室', '服务区南区办公室-光伏', 4, 0);
+
 -- 区域属性属性
 INSERT INTO `adm_area_attr` (`area_code`, `attr_org`, `mgr_org`, `leader`, `phone`, `open_date`, `floor_area`, `usable_area`, `floor`, `longitude`, `latitude`) VALUES ('321283124S3001', '常泰大桥服务区', '润扬大桥投资管理有限公司', 'xxx', '13000000000', '2025-01-01', 7250, 6000, NULL, 120.050937, 32.071956);
 INSERT INTO `adm_area_attr` (`area_code`, `attr_org`, `mgr_org`, `leader`, `phone`, `open_date`, `floor_area`, `usable_area`, `floor`, `longitude`, `latitude`) VALUES ('321283124S3002', '常泰大桥服务区', '润扬大桥投资管理有限公司', 'xxx', '13000000000', '2025-01-01', 7250, 6000, NULL, 120.052389, 32.070408);
@@ -140,6 +145,14 @@ INSERT INTO `adm_area_attr` (`area_code`, `attr_org`, `mgr_org`, `leader`, `phon
 INSERT INTO `adm_area_attr` (`area_code`, `attr_org`, `mgr_org`, `leader`, `phone`, `open_date`, `floor_area`, `usable_area`, `floor`, `longitude`, `latitude`) VALUES ('B-10210', '常泰大桥服务区', '润扬大桥投资管理有限公司', 'xxx', '13000000000', '2025-01-01', NULL, NULL, 1, 120.050937, 32.071956);
 INSERT INTO `adm_area_attr` (`area_code`, `attr_org`, `mgr_org`, `leader`, `phone`, `open_date`, `floor_area`, `usable_area`, `floor`, `longitude`, `latitude`) VALUES ('321283124S30010201', '常泰大桥服务区', '润扬大桥投资管理有限公司', 'xxx', '13000000000', '2025-01-01', NULL, NULL, 1, 120.050937, 32.071956);
 INSERT INTO `adm_area_attr` (`area_code`, `attr_org`, `mgr_org`, `leader`, `phone`, `open_date`, `floor_area`, `usable_area`, `floor`, `longitude`, `latitude`) VALUES ('321283124S30010202', '常泰大桥服务区', '润扬大桥投资管理有限公司', 'xxx', '13000000000', '2025-01-01', NULL, NULL, 1, 120.050937, 32.071956);
+INSERT INTO `adm_area_attr` (`area_code`, `attr_org`, `mgr_org`, `leader`, `phone`, `open_date`, `floor_area`, `usable_area`, `floor`, `longitude`, `latitude`) VALUES ('321283124S30015001', '常泰大桥服务区', '润扬大桥投资管理有限公司', 'xxx', '13000000000', '2025-01-01', 7250, 6000, NULL, 120.050937, 32.071956);
+INSERT INTO `adm_area_attr` (`area_code`, `attr_org`, `mgr_org`, `leader`, `phone`, `open_date`, `floor_area`, `usable_area`, `floor`, `longitude`, `latitude`) VALUES ('321283124S30015002', '常泰大桥服务区', '润扬大桥投资管理有限公司', 'xxx', '13000000000', '2025-01-01', 7250, 6000, NULL, 120.050937, 32.071956);
+INSERT INTO `adm_area_attr` (`area_code`, `attr_org`, `mgr_org`, `leader`, `phone`, `open_date`, `floor_area`, `usable_area`, `floor`, `longitude`, `latitude`) VALUES ('321283124S30015003', '常泰大桥服务区', '润扬大桥投资管理有限公司', 'xxx', '13000000000', '2025-01-01', 7250, 6000, NULL, 120.050937, 32.071956);
+INSERT INTO `adm_area_attr` (`area_code`, `attr_org`, `mgr_org`, `leader`, `phone`, `open_date`, `floor_area`, `usable_area`, `floor`, `longitude`, `latitude`) VALUES ('321283124S30025001', '常泰大桥服务区', '润扬大桥投资管理有限公司', 'xxx', '13000000000', '2025-01-01', 7250, 6000, NULL, 120.050937, 32.071956);
+INSERT INTO `adm_area_attr` (`area_code`, `attr_org`, `mgr_org`, `leader`, `phone`, `open_date`, `floor_area`, `usable_area`, `floor`, `longitude`, `latitude`) VALUES ('321283124S30025002', '常泰大桥服务区', '润扬大桥投资管理有限公司', 'xxx', '13000000000', '2025-01-01', 7250, 6000, NULL, 120.050937, 32.071956);
+INSERT INTO `adm_area_attr` (`area_code`, `attr_org`, `mgr_org`, `leader`, `phone`, `open_date`, `floor_area`, `usable_area`, `floor`, `longitude`, `latitude`) VALUES ('321283124S30025003', '常泰大桥服务区', '润扬大桥投资管理有限公司', 'xxx', '13000000000', '2025-01-01', 7250, 6000, NULL, 120.050937, 32.071956);
+INSERT INTO `adm_area_attr` (`area_code`, `attr_org`, `mgr_org`, `leader`, `phone`, `open_date`, `floor_area`, `usable_area`, `floor`, `longitude`, `latitude`) VALUES ('321283124S30025004', '常泰大桥服务区', '润扬大桥投资管理有限公司', 'xxx', '13000000000', '2025-01-01', 7250, 6000, NULL, 120.050937, 32.071956);
+
 
 
 -- 能源设施初始数据
@@ -162,9 +175,9 @@ INSERT INTO `adm_ems_facs` (`facs_code`, `facs_name`, `facs_category`, `facs_sub
 INSERT INTO `adm_ems_facs` (`facs_code`, `facs_name`, `facs_category`, `facs_subcategory`, `enable`, `ref_area`) VALUES ('Z-QT-01', '北区-其他设施',   'Z', 'Z999', 1, '321283124S3001');
 INSERT INTO `adm_ems_facs` (`facs_code`, `facs_name`, `facs_category`, `facs_subcategory`, `enable`, `ref_area`) VALUES ('Z-QT-02', '南区-其他设施',   'Z', 'Z999', 1, '321283124S3002');
 
-
 INSERT INTO `adm_ems_facs` (`facs_code`, `facs_name`, `facs_category`, `facs_subcategory`, `enable`, `ref_area`) VALUES ('NH01', '北区-能耗监测', 'W', 'W4', 1, '321283124S3001');
 INSERT INTO `adm_ems_facs` (`facs_code`, `facs_name`, `facs_category`, `facs_subcategory`, `enable`, `ref_area`) VALUES ('NH02', '南区-能耗监测', 'W', 'W4', 1, '321283124S3002');
+INSERT INTO `adm_ems_facs` (`facs_code`, `facs_name`, `facs_category`, `facs_subcategory`, `enable`, `ref_area`) VALUES ('NH03', '主路-能耗监测', 'W', 'W4', 1, '321283124S3003');
 INSERT INTO `adm_ems_facs` (`facs_code`, `facs_name`, `facs_category`, `facs_subcategory`, `enable`, `ref_area`) VALUES ('GCC01', '北区-光储充监测', 'W', 'W4', 1, '321283124S3001');
 INSERT INTO `adm_ems_facs` (`facs_code`, `facs_name`, `facs_category`, `facs_subcategory`, `enable`, `ref_area`) VALUES ('GCC02', '南区-光储充监测', 'W', 'W4', 1, '321283124S3002');
 INSERT INTO `adm_ems_facs` (`facs_code`, `facs_name`, `facs_category`, `facs_subcategory`, `enable`, `ref_area`) VALUES ('Charge01', '北区-充电桩监测', 'W', 'W4', 1, '321283124S3001');
@@ -200,6 +213,47 @@ INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `dev
 INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'Z020-N-AHU-1F-1', '南1F-1空调系统', '-', '-', '1', '综合楼-一楼', '321283124S30020101', '321283124S3002', 'M_Z020_DEV_BA_AHU', 'Z-KT-02', NULL, 'SYS_BA');
 INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'Z020-N-AHU-2F-1', '南2F-1空调系统', '-', '-', '1', '综合楼-二楼', '321283124S30020104', '321283124S3002', 'M_Z020_DEV_BA_AHU', 'Z-KT-02', NULL, 'SYS_BA');
 
+-- 光伏设备
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-B-COL-GFZL-1', '北区主楼光伏采集器1', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '北区主楼', '321283124S30015001', '321283124S3001', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH01', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-B-COL-GFZL-2', '北区主楼光伏采集器2', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '北区主楼', '321283124S30015001', '321283124S3001', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH01', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-B-COL-GFPD-1', '北区配电房光伏采集器', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '北区配电房', '321283124S30015002', '321283124S3001', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH01', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-B-COL-GFCP-1', '北区车棚光伏采集器1', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '北区车棚', '321283124S30015003', '321283124S3001', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH01', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-B-COL-GFCP-2', '北区车棚光伏采集器2', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '北区车棚', '321283124S30015003', '321283124S3001', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH01', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-B-COL-GFCP-3', '北区车棚光伏采集器3', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '北区车棚', '321283124S30015003', '321283124S3001', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH01', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-N-COL-GFZL-1', '南区主楼光伏采集器1', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '南区主楼', '321283124S30025001', '321283124S3002', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH02', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-N-COL-GFZL-2', '南区主楼光伏采集器2', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '南区主楼', '321283124S30025001', '321283124S3002', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH02', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-N-COL-GFPD-1', '南区配电房光伏采集器', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '南区配电房', '321283124S30025002', '321283124S3002', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH02', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-N-COL-GFCP-1', '南区车棚光伏采集器1', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '南区车棚', '321283124S30025003', '321283124S3002', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH02', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-N-COL-GFCP-2', '南区车棚光伏采集器2', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '南区车棚', '321283124S30025003', '321283124S3002', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH02', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-N-COL-GFCP-3', '南区车棚光伏采集器3', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '南区车棚', '321283124S30025003', '321283124S3002', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH02', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-N-COL-GFBG-1', '南区办公室光伏采集器', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '南区办公室', '321283124S30025004', '321283124S3002', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH02', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-ZX-COL-GF-1', '主线光伏采集器1', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '服务区主线', '321283124S3003', '321283124S3003', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH03', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-ZX-COL-GF-2', '主线光伏采集器2', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '服务区主线', '321283124S3003', '321283124S3003', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH03', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-ZX-COL-GF-3', '主线光伏采集器3', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '服务区主线', '321283124S3003', '321283124S3003', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH03', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-ZX-COL-GF-4', '主线光伏采集器4', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '服务区主线', '321283124S3003', '321283124S3003', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH03', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-ZX-COL-GF-5', '主线光伏采集器5', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '服务区主线', '321283124S3003', '321283124S3003', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH03', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-ZX-COL-GF-6', '主线光伏采集器6', 'Growatt-古瑞瓦特', 'Shine4G-X2-GD', '1', '服务区主线', '321283124S3003', '321283124S3003', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'NH03', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-B-INV-GFZL-1', '北区主楼光伏逆变器1', 'Growatt-古瑞瓦特', '-', '1', '北区主楼', '321283124S30015001', '321283124S3001', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E501', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-B-INV-GFZL-2', '北区主楼光伏逆变器2', 'Growatt-古瑞瓦特', '-', '1', '北区主楼', '321283124S30015001', '321283124S3001', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E501', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-B-INV-GFPD-1', '北区配电房光伏逆变器', 'Growatt-古瑞瓦特', '-', '1', '北区配电房', '321283124S30015002', '321283124S3001', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E501', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-B-INV-GFCP-1', '北区车棚光伏逆变器1', 'Growatt-古瑞瓦特', '-', '1', '北区车棚', '321283124S30015003', '321283124S3001', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E501', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-B-INV-GFCP-2', '北区车棚光伏逆变器2', 'Growatt-古瑞瓦特', '-', '1', '北区车棚', '321283124S30015003', '321283124S3001', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E501', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-B-INV-GFCP-3', '北区车棚光伏逆变器3', 'Growatt-古瑞瓦特', '-', '1', '北区车棚', '321283124S30015003', '321283124S3001', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E501', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-N-INV-GFZL-1', '南区主楼光伏逆变器1', 'Growatt-古瑞瓦特', '-', '1', '南区主楼', '321283124S30025001', '321283124S3002', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E502', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-N-INV-GFZL-2', '南区主楼光伏逆变器2', 'Growatt-古瑞瓦特', '-', '1', '南区主楼', '321283124S30025001', '321283124S3002', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E502', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-N-INV-GFPD-1', '南区配电房光伏逆变器', 'Growatt-古瑞瓦特', '-', '1', '南区配电房', '321283124S30025002', '321283124S3002', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E502', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-N-INV-GFCP-1', '南区车棚光伏逆变器1', 'Growatt-古瑞瓦特', '-', '1', '南区车棚', '321283124S30025003', '321283124S3002', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E502', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-N-INV-GFCP-2', '南区车棚光伏逆变器2', 'Growatt-古瑞瓦特', '-', '1', '南区车棚', '321283124S30025003', '321283124S3002', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E502', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-N-INV-GFCP-3', '南区车棚光伏逆变器3', 'Growatt-古瑞瓦特', '-', '1', '南区车棚', '321283124S30025003', '321283124S3002', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E502', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-N-INV-GFBG-1', '南区办公室光伏逆变器', 'Growatt-古瑞瓦特', '-', '1', '南区办公室', '321283124S30025004', '321283124S3002', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E502', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-ZX-INV-GF-1', '主线光伏逆变器1', 'Growatt-古瑞瓦特', '-', '1', '服务区主线', '321283124S3003', '321283124S3003', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E503', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-ZX-INV-GF-2', '主线光伏逆变器2', 'Growatt-古瑞瓦特', '-', '1', '服务区主线', '321283124S3003', '321283124S3003', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E503', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-ZX-INV-GF-3', '主线光伏逆变器3', 'Growatt-古瑞瓦特', '-', '1', '服务区主线', '321283124S3003', '321283124S3003', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E503', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-ZX-INV-GF-4', '主线光伏逆变器4', 'Growatt-古瑞瓦特', '-', '1', '服务区主线', '321283124S3003', '321283124S3003', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E503', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-ZX-INV-GF-5', '主线光伏逆变器5', 'Growatt-古瑞瓦特', '-', '1', '服务区主线', '321283124S3003', '321283124S3003', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E503', NULL, 'SYS_GF');
+INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ( 'E5-ZX-INV-GF-6', '主线光伏逆变器6', 'Growatt-古瑞瓦特', '-', '1', '服务区主线', '321283124S3003', '321283124S3003', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'E503', NULL, 'SYS_GF');
+
+
 -- mock设备
 INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ('GCZR-001', '光储设备1',    'xxx', 'xxx', 1, '北区广场', '321283124S300104', '321283124S3001',  'test', 'C101', NULL, 'SYS_GCC');
 INSERT INTO `adm_ems_device` (`device_code`, `device_name`, `device_brand`, `device_spec`, `device_status`, `location`, `location_ref`, `area_code`, `device_model`, `ref_facs`, `ps_code`, `subsystem_code`) VALUES ('GCZR-002', '光储设备2',    'xxx', 'xxx', 1, '北区广场', '321283124S300104', '321283124S3001',  'test', 'C101', NULL, 'SYS_GCC');
@@ -303,6 +357,10 @@ INSERT INTO `adm_ems_obj_model` (`model_code`, `model_name`, `obj_type`, `abilit
 INSERT INTO `adm_ems_obj_model` (`model_code`, `model_name`, `obj_type`, `ability_handler`, `event_handler`) VALUES ('M_W4_DEV_ELEC_MONITOR_BHZZ', '电力保护装置', 2, 'http://172.17.60.27:9203/ems-dev-adapter/elec-monitor-acrel/ct/abilityCall', NULL);
 INSERT INTO `adm_ems_obj_model` (`model_code`, `model_name`, `obj_type`, `ability_handler`, `event_handler`) VALUES ('M_W4_DEV_ELEC_MONITOR_DB', '多功能电表', 2, 'http://172.17.60.27:9203/ems-dev-adapter/elec-monitor-acrel/ct/abilityCall', NULL);
 
+INSERT INTO `adm_ems_obj_model` (`model_code`, `model_name`, `obj_type`, `ability_handler`, `event_handler`) VALUES ('M_E5_SYS_PHOTOVOLTAIC', '光伏系统', 3, 'http://172.17.60.27:9203/ems-dev-adapter/growatt/ct/abilityCall', NULL);
+INSERT INTO `adm_ems_obj_model` (`model_code`, `model_name`, `obj_type`, `ability_handler`, `event_handler`) VALUES ('M_W2_DEV_PHOTOVOLTAIC_COL', '光伏采集器', 2, 'http://172.17.60.27:9203/ems-dev-adapter/growatt/ct/abilityCall', NULL);
+INSERT INTO `adm_ems_obj_model` (`model_code`, `model_name`, `obj_type`, `ability_handler`, `event_handler`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', '光伏逆变器', 2, 'http://172.17.60.27:9203/ems-dev-adapter/growatt/ct/abilityCall', NULL);
+
 -- 对象属性数据
 -- 能耗监测属性
 INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_W4_SYS_BA', 'Protocol', 'interfaceType', '协议类型', NULL, 'String');
@@ -494,6 +552,82 @@ INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_na
 INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_W4_DEV_ELEC_MONITOR_DB', 'State', 'Temp', '环境温度', '℃', 'Value');
 INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_W4_DEV_ELEC_MONITOR_DB', 'Measure', 'EPI', '正向有功总电能', 'kW·h', 'Value');
 
+-- 光伏监控属性
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_W2_DEV_PHOTOVOLTAIC_COL', 'Base', 'sn', '设备SN', NULL, 'String');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_W2_DEV_PHOTOVOLTAIC_COL', 'Base', 'manufacturer', '厂家', NULL, 'String');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_W2_DEV_PHOTOVOLTAIC_COL', 'Base', 'model', '类型', NULL, 'String');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_W2_DEV_PHOTOVOLTAIC_COL', 'Base', 'netmode', '网络类型', NULL, 'String');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_W2_DEV_PHOTOVOLTAIC_COL', 'Base', 'lastUpdateTime', '数据最后接收时间', NULL, 'String');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'Base', 'sn', '设备SN', NULL, 'String');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'Base', 'dataloggerSn', '采集器SN', NULL, 'String');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'Base', 'manufacturer', '厂家', NULL, 'String');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'Base', 'model', '类型', NULL, 'String');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'Base', 'type', '设备类型', NULL, 'Enum');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'Base', 'status', '设备状态码', NULL, 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'Base', 'statusText', '设备状态', NULL, 'String');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'Base', 'lastUpdateTime', '数据最后接收时间', NULL, 'String');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'Base', 'time', '实时数据采集时间', NULL, 'String');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'pac', '交流输出功率', 'W', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'ppv', 'PV总功率', 'W', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'ppv1', 'PV1功率', 'W', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'ppv2', 'PV2功率', 'W', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'ppv3', 'PV3功率', 'W', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'ppv4', 'PV4功率', 'W', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vpv1', 'PV1电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vpv2', 'PV2电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vpv3', 'PV3电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vpv4', 'PV4电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vpv5', 'PV5电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vpv6', 'PV6电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vpv7', 'PV7电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vpv8', 'PV8电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString1', '组串1电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString2', '组串2电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString3', '组串3电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString4', '组串4电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString5', '组串5电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString6', '组串6电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString7', '组串7电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString8', '组串8电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString9', '组串9电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString10', '组串10电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString11', '组串11电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString12', '组串12电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString13', '组串13电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString14', '组串14电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString15', '组串15电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vString16', '组串16电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'pBusVoltage', '正母线电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'nBusVoltage', '负母线电压', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vacr', 'R相电压(交流)', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vacs', 'S相电压(交流)', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vact', 'T相电压(交流)', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vacRs', 'RS线电压(交流)', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vacSt', 'ST线电压(交流)', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'vacTr', 'TR线电压(交流)', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'temperature', '逆变器温度', '℃', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'temperature1', '温度2', '℃', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'temperature2', '温度3', '℃', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'temperature4', '温度4', '℃', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'temperature3', '温度5', '℃', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'fac', '电网频率', 'Hz', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'pf', '功率因数', NULL, 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'faultCode1', '故障码1', NULL, 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'faultCode2', '故障码2', NULL, 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'faultType', '故障类型', NULL, 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'faultValue', '故障值', NULL, 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'warnCode', '告警码', NULL, 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'deratingMode', '降额模式', NULL, 'Enum');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'gfci', '漏电电流', 'mA', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'pvIso', 'PV绝缘阻抗', 'kOhm', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'pidBus', 'PID母线', 'V', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'opFullwatt', '满载运行时间', 'h', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'State', 'timeTotal', '总运行时间', 'h', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'Measure', 'eacToday', '今日发电量', 'kW·h', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'Measure', 'eacTotal', '累计发电量', 'kW·h', 'Value');
+INSERT INTO `adm_ems_obj_attr` (`model_code`, `attr_group`, `attr_key`, `attr_name`, `attr_unit`, `attr_value_type`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'Measure', 'epvTotal', 'PV累计发电量', 'kW·h', 'Value');
+
+
 INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_W4_SYS_BA', 'interfaceStatus', '1', '正常');
 INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_W4_SYS_BA', 'interfaceStatus', '0', '断开');
 INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_Z010_SYS_SQUARE_LIGHT', 'interfaceStatus', '1', '正常');
@@ -576,6 +710,19 @@ INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `at
 INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_Z020_DEV_BA_LIGHT', 'Switch', '0', '关闭');
 INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_Z020_DEV_BA_LIGHT', 'Switch', '1', '开启');
 
+INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'type', '1', '逆变器(含MAX)');
+INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'type', '2', '储能机');
+INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'type', '3', '其他设备');
+INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'type', '4', 'MAX(单MAX)');
+INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'type', '5', 'SPH');
+INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'type', '6', 'SPA');
+INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'type', '7', 'MIN');
+INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'type', '8', 'PCS');
+INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'type', '9', 'HPS');
+INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'type', '10', 'PBD');
+INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'deratingMode', '1', '开启');
+INSERT INTO `adm_ems_obj_attr_enum` (`model_code`, `attr_key`, `attr_value`, `attr_value_name`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'deratingMode', '0', '关闭');
+
 -- 对象属性
 INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('SYS_BA', 'M_W4_SYS_BA', 'interfaceType', 'http', NULL);
 INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('SYS_BA', 'M_W4_SYS_BA', 'url', 'http://172.17.50.186:80', NULL);
@@ -1181,6 +1328,66 @@ INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `att
 INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('Z020-N-WP-1', 'M_Z020_DEV_BA_WT', 'ddcTag', 'DDC1地下室', NULL);
 INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('Z020-N-WP-2', 'M_Z020_DEV_BA_WT', 'ddcTag', 'DDC1地下室', NULL);
 
+-- 光伏设备静态属性
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-COL-GFZL-1', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'ZBK0E8U01A', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-COL-GFZL-2', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'ZBK0E8U08H', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-COL-GFPD-1', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'LGK2E631S2', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-COL-GFCP-1', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'LGK2E631R3', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-COL-GFCP-2', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'ZBK0E9L02H', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-COL-GFCP-3', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'ZBK0E9L0VA', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-COL-GFZL-1', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'ZBK0E8510V', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-COL-GFZL-2', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'ZBK0E850EC', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-COL-GFPD-1', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'PWQ0E7C0CZ', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-COL-GFCP-1', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'LGK2E6321Q', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-COL-GFCP-2', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'ZBK0E9L0QD', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-COL-GFCP-3', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'ZBK0E9L0N0', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-COL-GFBG-1', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'ZBK0E9L0QJ', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-COL-GF-1', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'ZBK0E9L0QG', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-COL-GF-2', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'ZBK0E9L0QH', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-COL-GF-3', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'ZBK0E8U010', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-COL-GF-4', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'ZBK0E8519V', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-COL-GF-5', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'ZBK0E9L0QF', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-COL-GF-6', 'M_W2_DEV_PHOTOVOLTAIC_COL', 'sn', 'ZBK0E9L0MV', NULL);
+
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-INV-GFZL-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'GCN4E9503G', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-INV-GFZL-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'ZBK0E8U01A', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-INV-GFZL-2', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'GCN4E9503H', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-INV-GFZL-2', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'ZBK0E8U08H', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-INV-GFPD-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'THM9E6L00R', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-INV-GFPD-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'LGK2E631S2', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-INV-GFCP-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'THM9E6L00J', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-INV-GFCP-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'LGK2E631R3', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-INV-GFCP-2', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'GCN5EX9028', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-INV-GFCP-2', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'ZBK0E9L02H', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-INV-GFCP-3', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'GCN5EX9024', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-B-INV-GFCP-3', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'ZBK0E9L0VA', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-INV-GFZL-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'GCN5EX900D', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-INV-GFZL-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'ZBK0E8510V', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-INV-GFZL-2', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'GCN5EX900E', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-INV-GFZL-2', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'ZBK0E850EC', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-INV-GFPD-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'VUQ0E7L0BJ', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-INV-GFPD-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'PWQ0E7C0CZ', NULL);
+-- INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-INV-GFCP-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', '', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-INV-GFCP-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'LGK2E6321Q', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-INV-GFCP-2', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'GCN5EX9022', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-INV-GFCP-2', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'ZBK0E9L0QD', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-INV-GFCP-3', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'GCN5EX902H', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-INV-GFCP-3', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'ZBK0E9L0N0', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-INV-GFBG-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'GCN5EX902L', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-N-INV-GFBG-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'ZBK0E9L0QJ', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-INV-GF-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'GCN5EX902J', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-INV-GF-1', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'ZBK0E9L0QG', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-INV-GF-2', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'GCN5EX902M', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-INV-GF-2', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'ZBK0E9L0QH', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-INV-GF-3', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'GCN4E95032', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-INV-GF-3', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'ZBK0E8U010', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-INV-GF-4', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'GCN5EX900F', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-INV-GF-4', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'ZBK0E8519V', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-INV-GF-5', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'GCN5EX902F', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-INV-GF-5', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'ZBK0E9L0QF', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-INV-GF-6', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'sn', 'GCN5EX902G', NULL);
+INSERT INTO `adm_ems_obj_attr_value` (`obj_code`, `model_code`, `attr_key`, `attr_value`, `update_time`) VALUES ('E5-ZX-INV-GF-6', 'M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'dataloggerSn', 'ZBK0E9L0MV', NULL);
+
 
 -- 对象能力数据
 INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_W4_SYS_BA', 'MeterReadingTotal', '全量抄报-网关', '网关-测点批量抄报', null, 1);
@@ -1206,6 +1413,13 @@ 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_W4_SYS_ELEC_MONITOR', 'SyncDevAttrAll', '全量刷新状态', '全量刷新状态', null, 1);
 INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_W4_DEV_ELEC_MONITOR_BHZZ', 'SyncDevAttr', '刷新状态', '刷新设备状态', null, 1);
 INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_W4_DEV_ELEC_MONITOR_DB', 'SyncDevAttr', '刷新状态', '刷新设备状态', null, 1);
+INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_E5_SYS_PHOTOVOLTAIC', 'SyncDevCollector', '同步采集器设备', '从Growatt API同步采集器设备状态和属性', null, 1);
+INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_E5_SYS_PHOTOVOLTAIC', 'SyncDevInverter', '同步逆变器设备', '从Growatt API同步逆变器设备列表和基础属性', null, 1);
+INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_E5_SYS_PHOTOVOLTAIC', 'CollectInverterData', '采集逆变器数据', '批量采集所有逆变器的实时运行数据', null, 1);
+INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_E5_SYS_PHOTOVOLTAIC', 'SyncAll', '全量同步', '同步所有设备数据(采集器+逆变器+实时数据)', null, 1);
+INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_W2_DEV_PHOTOVOLTAIC_COL', 'SyncAttr', '同步属性', '从API同步当前采集器的属性数据', null, 1);
+INSERT INTO `adm_ems_obj_ability` (`model_code`, `ability_key`, `ability_name`, `ability_desc`, `param_definition`, `hidden_flag`) VALUES ('M_E5_DEV_PHOTOVOLTAIC_INVERTER', 'SyncAttr', '同步属性', '从API同步当前逆变器的实时数据', null, 1);
+
 
 
 -- 对象事件数据
@@ -1779,7 +1993,7 @@ INSERT INTO adm_meter_reading (`device_code`, `area_code`, `year`, `meter_month`
 INSERT INTO `adm_ems_subsystem` (`system_code`, `system_name`, `short_name`, `model_code`, `man_facturer`, `contact_person`, `contact_number`, `maintainer_person`, `maintainer_number`, `descr`) VALUES ('SYS_BA', 'BA楼宇监控采集', 'BA楼宇监控采集', 'M_W4_SYS_BA','能耗监测厂商', '东边', '', '', '', NULL);
 INSERT INTO `adm_ems_subsystem` (`system_code`, `system_name`, `short_name`, `model_code`, `man_facturer`, `contact_person`, `contact_number`, `maintainer_person`, `maintainer_number`, `descr`) VALUES ('SYS_ZHZM', '智慧照明系统', '智慧照明', 'M_Z010_SYS_SQUARE_LIGHT', '智慧照明厂商', '林工', '1212121121', '刘工', '1212221111', NULL);
 INSERT INTO `adm_ems_subsystem` (`system_code`, `system_name`, `short_name`, `model_code`, `man_facturer`, `contact_person`, `contact_number`, `maintainer_person`, `maintainer_number`, `descr`) VALUES ('SYS_DLJK', '电力监控系统', '电力监控', 'M_W4_SYS_ELEC_MONITOR', '安科瑞', 'gzl', '1212121121', 'gzl', '1212221111', NULL);
-INSERT INTO `adm_ems_subsystem` (`system_code`, `system_name`, `short_name`, `model_code`, `man_facturer`, `contact_person`, `contact_number`, `maintainer_person`, `maintainer_number`, `descr`) VALUES ('SYS_GF', '光伏系统', '光伏', 'M_TEST', '南通', '张', '1380000', '李工', '123123', NULL);
+INSERT INTO `adm_ems_subsystem` (`system_code`, `system_name`, `short_name`, `model_code`, `man_facturer`, `contact_person`, `contact_number`, `maintainer_person`, `maintainer_number`, `descr`) VALUES ('SYS_GF', '光伏系统', '光伏', 'M_E5_SYS_PHOTOVOLTAIC', '古瑞瓦特', '张', '1380000', '李工', '123123', NULL);
 INSERT INTO `adm_ems_subsystem` (`system_code`, `system_name`, `short_name`, `model_code`, `man_facturer`, `contact_person`, `contact_number`, `maintainer_person`, `maintainer_number`, `descr`) VALUES ('SYS_CN', '储能系统', '储能', 'M_TEST','储能厂商', '王', '122112', '陈', '21212', NULL);
 INSERT INTO `adm_ems_subsystem` (`system_code`, `system_name`, `short_name`, `model_code`, `man_facturer`, `contact_person`, `contact_number`, `maintainer_person`, `maintainer_number`, `descr`) VALUES ('SYS_CD', '充电桩系统', '充电桩', 'M_TEST', '特来电', '张三', '1212121121', '刘工', '1212221111', NULL);
 INSERT INTO `adm_ems_subsystem` (`system_code`, `system_name`, `short_name`, `model_code`, `man_facturer`, `contact_person`, `contact_number`, `maintainer_person`, `maintainer_number`, `descr`) VALUES ('SYS_GCC', '光储充系统', '光储充', 'M_TEST', '光储充厂商', '张三', '1212121121', '刘工', '1212221111', NULL);

+ 3 - 2
ems/sql/ems_server.sql

@@ -655,7 +655,8 @@ create table adm_ems_device  (
   `create_time`     datetime        default CURRENT_TIMESTAMP    comment '创建时间',
   `update_time`     datetime        default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '更新时间',
   primary key (`id`),
-  unique key ux_device_code(`device_code`)
+  unique key ux_device_code(`device_code`),
+  index idx_device_code (device_code)
 ) engine=innodb auto_increment=1 comment = '能源设备表';
 
 
@@ -800,7 +801,7 @@ create table adm_ems_obj_ability_call_log  (
   `res_time`        datetime        default null                 comment '响应时间',
   `res_payload`     mediumtext      default null                 comment '响应内容',
   primary key (`id`),
-  key i_ability_call_log(`obj_code`, `model_code`, `ability_key`, `call_time`)
+  INDEX idx_covering (model_code,call_time,obj_code,ability_key,call_status, id)
 ) engine=innodb auto_increment=1 comment = '能源对象能力调用日志表';
 
 

Некоторые файлы не были показаны из-за большого количества измененных файлов