Explorar o código

增加频率核心计算及缓存机制

xusl hai 1 ano
pai
achega
ffdd6d62c3

+ 2 - 0
backend/src/main/java/com/jiayue/pfr/PfrApplication.java

@@ -9,6 +9,7 @@ import org.springframework.cache.ehcache.EhCacheCacheManager;
 import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.core.io.ClassPathResource;
+import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.scheduling.annotation.EnableScheduling;
 
 
@@ -21,6 +22,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 @SpringBootApplication
 @EnableScheduling
 @EnableCaching
+@EnableAsync
 @MapperScan("com.jiayue.pfr.mapper.*")
 public class PfrApplication {
     public static void main(String[] args) {

+ 2 - 0
backend/src/main/java/com/jiayue/pfr/config/MybatisPlusConfig.java

@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
 
+import com.jiayue.pfr.service.cmf.SysParameterService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 

+ 30 - 0
backend/src/main/java/com/jiayue/pfr/config/SystemInitConifg.java

@@ -0,0 +1,30 @@
+package com.jiayue.pfr.config;
+
+import com.jiayue.pfr.service.cmf.SysParameterService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 系统启动配置
+ *
+ * @author jy
+ * @since 2023/11/10
+ */
+@Configuration
+public class SystemInitConifg {
+    @Autowired
+    SysParameterService sysParameterService;
+
+    @Bean
+    public void initSysParameter() {
+        sysParameterService.queryByKey("ieSignal","ON");
+        sysParameterService.queryByKey("dbMin","49.95");
+        sysParameterService.queryByKey("dbMax","50.05");
+        sysParameterService.queryByKey("capacity","100");
+        sysParameterService.queryByKey("epMin","0.02");
+        sysParameterService.queryByKey("limitMin","0.2");
+        sysParameterService.queryByKey("epMax","0.05");
+        sysParameterService.queryByKey("limitMax","0.1");
+    }
+}

+ 31 - 31
backend/src/main/java/com/jiayue/pfr/config/TestFmRandom.java

@@ -23,36 +23,36 @@ public class TestFmRandom {
 
     @Bean
     public void generateFrequency() throws Exception{
-        new Thread(()->{
-            this.random = new SecureRandom();
-            this.minFrequency = new BigDecimal("49.9");
-            this.maxFrequency = new BigDecimal("200.1");
-            while (true){
-                // 返回一个在此范围内(包括边界)的随机BigDecimal值。
-                BigDecimal range = maxFrequency.subtract(minFrequency);
-                BigDecimal fraction = new BigDecimal(random.nextDouble());
-                BigDecimal fm = minFrequency.add(range.multiply(fraction)).setScale(3, BigDecimal.ROUND_HALF_UP);
-                if (testPrevTime==0){
-                    CacheConstants.activePower = fm;
-                }
-                else{
-                    // 判断当前时间与上次时间是否同一秒内
-                    if (DateUtil.date(System.currentTimeMillis()).getSeconds()!=DateUtil.date(testPrevTime).getSeconds()){
-                        CacheConstants.activePower = fm;
-                    }
-                }
-                testPrevTime = System.currentTimeMillis();
-
-                // 往池子里加入频率
-                DataBean dataBean = new DataBean();
-                dataBean.setF(new BigDecimal("50"));
-                DataBeanPacker.getInstance().setLastDataBean(dataBean);
-                try {
-                    Thread.sleep(200);
-                } catch (InterruptedException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        }).start();
+//        new Thread(()->{
+//            this.random = new SecureRandom();
+//            this.minFrequency = new BigDecimal("49.9");
+//            this.maxFrequency = new BigDecimal("200.1");
+//            while (true){
+//                // 返回一个在此范围内(包括边界)的随机BigDecimal值。
+//                BigDecimal range = maxFrequency.subtract(minFrequency);
+//                BigDecimal fraction = new BigDecimal(random.nextDouble());
+//                BigDecimal fm = minFrequency.add(range.multiply(fraction)).setScale(3, BigDecimal.ROUND_HALF_UP);
+//                if (testPrevTime==0){
+//                    CacheConstants.activePower = fm;
+//                }
+//                else{
+//                    // 判断当前时间与上次时间是否同一秒内
+//                    if (DateUtil.date(System.currentTimeMillis()).getSeconds()!=DateUtil.date(testPrevTime).getSeconds()){
+//                        CacheConstants.activePower = fm;
+//                    }
+//                }
+//                testPrevTime = System.currentTimeMillis();
+//
+//                // 往池子里加入频率
+//                DataBean dataBean = new DataBean();
+//                dataBean.setF(new BigDecimal("50"));
+//                DataBeanPacker.getInstance().setLastDataBean(dataBean);
+//                try {
+//                    Thread.sleep(200);
+//                } catch (InterruptedException e) {
+//                    throw new RuntimeException(e);
+//                }
+//            }
+//        }).start();
     }
 }

+ 8 - 1
backend/src/main/java/com/jiayue/pfr/constant/CacheConstants.java

@@ -4,6 +4,8 @@ import com.jiayue.pfr.dto.FmDataBeanDto;
 import com.jiayue.pfr.protocol.frequency.DataBean;
 
 import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -19,6 +21,11 @@ public class CacheConstants {
 
     public static ConcurrentHashMap<Long, FmDataBeanDto> fmMap = new ConcurrentHashMap<>();
 
-    public static BigDecimal activePower = new BigDecimal(0);
+//    public static FmDataBeanDto lastFmDataBeanDto = new FmDataBeanDto();
+
+    public static BigDecimal activePower = new BigDecimal(-99);
+
+    // 调频动作信号 ON: 动作信号 , OFF: 复归信号
+    public static String fmAct = "OFF";
 
 }

+ 36 - 0
backend/src/main/java/com/jiayue/pfr/controller/alg/FrequencyController.java

@@ -0,0 +1,36 @@
+package com.jiayue.pfr.controller.alg;
+
+import com.jiayue.pfr.constant.CustomException;
+import com.jiayue.pfr.protocol.frequency.DataBean;
+import com.jiayue.pfr.protocol.frequency.DataBeanPacker;
+import com.jiayue.pfr.util.SaResultRefit;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+
+import java.math.BigDecimal;
+
+/**
+ * 频率控制类
+ *
+ * @author jy
+ * @since 2023/11/10
+ */
+@RestController
+@RequestMapping("/frequencyController")
+@Slf4j
+public class FrequencyController {
+    /**
+     * 手动调试频率-有功
+     */
+    @PostMapping(value = "/testFmAct")
+    public SaResultRefit testFmAct(@RequestParam("fm") String fm, @RequestParam("act") String act) throws CustomException {
+        try {
+            DataBean dataBean = new DataBean();
+            dataBean.setF(new BigDecimal(fm));
+            DataBeanPacker.getInstance().setLastDataBean(dataBean);
+            return SaResultRefit.ok("调试设定完成");
+        } catch (Exception e) {
+            throw new CustomException("手动调试频率-有功异常", e);
+        }
+    }
+}

+ 25 - 0
backend/src/main/java/com/jiayue/pfr/dto/SagFormulaDto.java

@@ -0,0 +1,25 @@
+package com.jiayue.pfr.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 下垂公式属性
+ *
+ * @author jy
+ * @since 2023/11/09
+ */
+@Data
+public class SagFormulaDto {
+    // 频率扰动 UP:频率上扰 DOWN:频率下扰
+    private String fmDisturb = "";
+    // 场站额定容量 MW
+    private BigDecimal capacity;
+    // 调频死区
+    private BigDecimal db;
+    // 功率限幅值
+    private BigDecimal limit;
+    // 调差率
+    private BigDecimal ep;
+}

+ 16 - 8
backend/src/main/java/com/jiayue/pfr/job/FmJob.java → backend/src/main/java/com/jiayue/pfr/job/GetFmJob.java

@@ -1,32 +1,36 @@
 package com.jiayue.pfr.job;
 
-import cn.hutool.core.date.DateUtil;
 import cn.hutool.json.JSONUtil;
 import com.jiayue.pfr.constant.CacheConstants;
 import com.jiayue.pfr.dto.FmDataBeanDto;
-import com.jiayue.pfr.entity.SysParameter;
 import com.jiayue.pfr.protocol.frequency.DataBean;
 import com.jiayue.pfr.protocol.frequency.DataBeanPacker;
+import com.jiayue.pfr.service.alg.GetFmEvent;
 import com.jiayue.pfr.service.cmf.SysParameterService;
 import com.jiayue.pfr.service.di.WebSocketServer;
-import com.jiayue.pfr.util.DateUtils;
 import org.apache.commons.lang3.time.DateFormatUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
-import java.util.Date;
 
 /**
  * 每200毫秒从池子中获取频率等信息
- * @author jy
+ * @author xsl
  * @since 2023/10/30
  */
 @Service
-public class FmJob {
+public class GetFmJob {
     @Autowired
     SysParameterService sysParameterService;
+    @Autowired
+    ApplicationEventPublisher applicationEventPublisher;
+
+    private static final Logger fLogger = LoggerFactory.getLogger("FLogger");
 
-    @Scheduled(fixedRate = 2000)
+    @Scheduled(fixedRate = 200)
     void startFmCal() throws Exception{
         // 从池子里取频率信息
         DataBean dataBean = DataBeanPacker.getInstance().getLastDataBean();
@@ -42,7 +46,11 @@ public class FmJob {
         fmDataBeanDto.setActivePower(CacheConstants.activePower);
         long currentTime = System.currentTimeMillis();
         fmDataBeanDto.setTime(DateFormatUtils.format(currentTime, "yyyy-MM-dd HH:mm:ss.SSS"));
-        WebSocketServer.sendInfo(JSONUtil.toJsonStr(fmDataBeanDto));
+
+//        CacheConstants.lastFmDataBeanDto = fmDataBeanDto;
+//        fLogger.info("获取频率定时");
+        // 调用事件
+        applicationEventPublisher.publishEvent(new GetFmEvent(fmDataBeanDto));
 
     }
 }

+ 117 - 0
backend/src/main/java/com/jiayue/pfr/service/alg/CoreAlgListener.java

@@ -0,0 +1,117 @@
+package com.jiayue.pfr.service.alg;
+
+import cn.hutool.json.JSONUtil;
+import com.jiayue.pfr.constant.CacheConstants;
+import com.jiayue.pfr.dto.FmDataBeanDto;
+import com.jiayue.pfr.dto.SagFormulaDto;
+import com.jiayue.pfr.service.cmf.SysParameterService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+
+/**
+ * 核心计算监听
+ *
+ * @author xsl
+ * @since 2023/11/09
+ */
+@Component
+public class CoreAlgListener implements ApplicationListener<GetFmEvent> {
+    private static final Logger fLogger = LoggerFactory.getLogger("FLogger");
+
+    @Autowired
+    SysParameterService sysParameterService;
+
+    @Async
+    @Override
+    public void onApplicationEvent(GetFmEvent getFmEvent) {
+        // 判断一次调频是否投入/退出
+        String ieSignal = sysParameterService.queryByKey("ieSignal","ON");
+        if ("ON".equals(ieSignal)){
+            // 投入,获取最新频率
+            FmDataBeanDto fmDataBeanDto = getFmEvent.getFmDataBeanDto();
+            if (fmDataBeanDto.getF().compareTo(new BigDecimal("-99"))!=0){
+                SagFormulaDto sagFormulaDto = genSagFormulaAttr(fmDataBeanDto);
+                // 判断频率是否超死区
+                if (!"".equals(sagFormulaDto.getFmDisturb())){
+                    if ("OFF".equals(CacheConstants.fmAct)){
+                        CacheConstants.fmAct = "ON";
+                        // 计算有功-频率下垂公式=>∆P
+                        BigDecimal dtp = sagFormulaCal(sagFormulaDto,fmDataBeanDto);
+                        // 给AGC闭锁调用104
+
+                        // 上传PMU、EMS数据
+                        fLogger.info("超出死区频率:"+sagFormulaDto.getDb()+ " 当前频率:"+fmDataBeanDto.getF()+" 时间:"+fmDataBeanDto.getTime());
+                    }
+                }
+                else{
+                    // 判断是否有过动作信号
+                    if ("ON".equals(CacheConstants.fmAct)){
+                        fLogger.info("频率恢复,当前频率:"+fmDataBeanDto.getF()+" 时间:"+fmDataBeanDto.getTime());
+                        // 做复归通知,AGC和PMU
+                        CacheConstants.fmAct = "OFF";
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * 获取下垂公式属性
+     * @param fmDataBeanDto
+     * @return
+     */
+    private SagFormulaDto genSagFormulaAttr(FmDataBeanDto fmDataBeanDto){
+        SagFormulaDto sagFormulaDto = new SagFormulaDto();
+        // 单位: Hz  调频死区下限值
+        String dbMin = sysParameterService.queryByKey("dbMin","49.95");
+        String dbMax = sysParameterService.queryByKey("dbMax","50.05");
+        // 获取场站额定功率
+        String capacity = sysParameterService.queryByKey("capacity","100");
+        sagFormulaDto.setCapacity(new BigDecimal(capacity));
+        // 判断频率是否超死区
+        if (fmDataBeanDto.getF().compareTo(new BigDecimal(dbMax))==1){
+            // 频率上扰
+            sagFormulaDto.setFmDisturb("UP");
+            String epMin = sysParameterService.queryByKey("epMin","0.02");
+            sagFormulaDto.setEp(new BigDecimal(epMin));
+            sagFormulaDto.setDb(new BigDecimal(dbMax));
+            String limitMin = sysParameterService.queryByKey("limitMin","0.2");
+            sagFormulaDto.setLimit(new BigDecimal(limitMin));
+        }
+        else{
+            if (fmDataBeanDto.getF().compareTo(new BigDecimal(dbMin))==-1){
+                // 频率下扰
+                sagFormulaDto.setFmDisturb("DOWN");
+                String epMax = sysParameterService.queryByKey("epMax","0.05");
+                sagFormulaDto.setEp(new BigDecimal(epMax));
+                sagFormulaDto.setDb(new BigDecimal(dbMin));
+                String limitMax = sysParameterService.queryByKey("limitMax","0.1");
+                sagFormulaDto.setLimit(new BigDecimal(limitMax));
+            }
+        }
+
+        return sagFormulaDto;
+    }
+
+    /**
+     * 计算下垂公式∆P
+     * @param sagFormulaDto
+     * @return
+     */
+    private BigDecimal sagFormulaCal(SagFormulaDto sagFormulaDto,FmDataBeanDto fmDataBeanDto){
+        BigDecimal difference =  fmDataBeanDto.getF().subtract(sagFormulaDto.getLimit());
+        BigDecimal differencetemp = difference.divide(new BigDecimal("50"),4,BigDecimal.ROUND_HALF_UP);
+        BigDecimal eptemp = new BigDecimal("-1").divide(sagFormulaDto.getEp(),4,BigDecimal.ROUND_HALF_UP);
+        // ∆P结果
+        BigDecimal dtp = differencetemp.multiply(eptemp).multiply(sagFormulaDto.getCapacity());
+        return dtp;
+    }
+}

+ 22 - 0
backend/src/main/java/com/jiayue/pfr/service/alg/GetFmEvent.java

@@ -0,0 +1,22 @@
+package com.jiayue.pfr.service.alg;
+
+import com.jiayue.pfr.dto.FmDataBeanDto;
+import lombok.Getter;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * 获取频率事件
+ *
+ * @author xsl
+ * @since 2023/11/09
+ */
+public class GetFmEvent extends ApplicationEvent {
+
+    @Getter
+    private final FmDataBeanDto fmDataBeanDto;
+
+    public GetFmEvent(FmDataBeanDto source) {
+        super(source);
+        this.fmDataBeanDto = source;
+    }
+}

+ 32 - 0
backend/src/main/java/com/jiayue/pfr/service/alg/SendFmSocketListener.java

@@ -0,0 +1,32 @@
+package com.jiayue.pfr.service.alg;
+
+import cn.hutool.json.JSONUtil;
+import com.jiayue.pfr.service.di.WebSocketServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+
+/**
+ * 发送频率给前端监听
+ *
+ * @author xsl
+ * @since 2023/11/09
+ */
+@Component
+public class SendFmSocketListener implements ApplicationListener<GetFmEvent> {
+    private static final Logger fLogger = LoggerFactory.getLogger("FLogger");
+    @Async
+    @Override
+    public void onApplicationEvent(GetFmEvent getFmEvent) {
+        try {
+            WebSocketServer.sendInfo(JSONUtil.toJsonStr(getFmEvent.getFmDataBeanDto()));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

+ 0 - 4
backend/src/main/java/com/jiayue/pfr/service/cmf/impl/SysParameterServiceImpl.java

@@ -40,11 +40,7 @@ public class SysParameterServiceImpl extends ServiceImpl<SysParameterMapper, Sys
             return defaultValue;
         }
         return sysParameter.getSysValue();
-
-
-
     }
-
     /**
      * 新增系统参数
      *

+ 2 - 6
backend/src/main/resources/ehcache-setting.xml

@@ -14,10 +14,6 @@
   <cache name="pfrcache"
          maxElementsOnDisk="200"
          maxElementsInMemory="10000"
-         eternal="false"
-         timeToIdleSeconds="120"
-         timeToLiveSeconds="120">
-    <searchable/>
-
-  </cache>
+         eternal="true"
+         />
 </ehcache>

+ 18 - 26
ui/package-lock.json

@@ -13,7 +13,7 @@
         "axios": "0.24.0",
         "clipboard": "2.0.8",
         "core-js": "3.25.3",
-        "echarts": "5.4.0",
+        "echarts": "^4.8.0",
         "element-ui": "2.15.12",
         "file-saver": "2.0.5",
         "fingerprintjs2": "^2.1.4",
@@ -7032,13 +7032,11 @@
       "license": "MIT"
     },
     "node_modules/echarts": {
-      "version": "5.4.0",
-      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.4.0.tgz",
-      "integrity": "sha512-uPsO9VRUIKAdFOoH3B0aNg7NRVdN7aM39/OjovjO9MwmWsAkfGyeXJhK+dbRi51iDrQWliXV60/XwLA7kg3z0w==",
-      "license": "Apache-2.0",
+      "version": "4.9.0",
+      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-4.9.0.tgz",
+      "integrity": "sha512-+ugizgtJ+KmsJyyDPxaw2Br5FqzuBnyOWwcxPKO6y0gc5caYcfnEUIlNStx02necw8jmKmTafmpHhGo4XDtEIA==",
       "dependencies": {
-        "tslib": "2.3.0",
-        "zrender": "5.4.0"
+        "zrender": "4.3.2"
       }
     },
     "node_modules/editorconfig": {
@@ -18313,6 +18311,7 @@
       "version": "2.3.0",
       "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
       "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
+      "dev": true,
       "license": "0BSD"
     },
     "node_modules/tty-browserify": {
@@ -20663,13 +20662,9 @@
       "license": "ISC"
     },
     "node_modules/zrender": {
-      "version": "5.4.0",
-      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.4.0.tgz",
-      "integrity": "sha512-rOS09Z2HSVGFs2dn/TuYk5BlCaZcVe8UDLLjj1ySYF828LATKKdxuakSZMvrDz54yiKPDYVfjdKqcX8Jky3BIA==",
-      "license": "BSD-3-Clause",
-      "dependencies": {
-        "tslib": "2.3.0"
-      }
+      "version": "4.3.2",
+      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-4.3.2.tgz",
+      "integrity": "sha512-bIusJLS8c4DkIcdiK+s13HiQ/zjQQVgpNohtd8d94Y2DnJqgM1yjh/jpDb8DoL6hd7r8Awagw8e3qK/oLaWr3g=="
     }
   },
   "dependencies": {
@@ -25750,12 +25745,11 @@
       }
     },
     "echarts": {
-      "version": "5.4.0",
-      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.4.0.tgz",
-      "integrity": "sha512-uPsO9VRUIKAdFOoH3B0aNg7NRVdN7aM39/OjovjO9MwmWsAkfGyeXJhK+dbRi51iDrQWliXV60/XwLA7kg3z0w==",
+      "version": "4.9.0",
+      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-4.9.0.tgz",
+      "integrity": "sha512-+ugizgtJ+KmsJyyDPxaw2Br5FqzuBnyOWwcxPKO6y0gc5caYcfnEUIlNStx02necw8jmKmTafmpHhGo4XDtEIA==",
       "requires": {
-        "tslib": "2.3.0",
-        "zrender": "5.4.0"
+        "zrender": "4.3.2"
       }
     },
     "editorconfig": {
@@ -34135,7 +34129,8 @@
     "tslib": {
       "version": "2.3.0",
       "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
-      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
+      "dev": true
     },
     "tty-browserify": {
       "version": "0.0.0",
@@ -35892,12 +35887,9 @@
       }
     },
     "zrender": {
-      "version": "5.4.0",
-      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.4.0.tgz",
-      "integrity": "sha512-rOS09Z2HSVGFs2dn/TuYk5BlCaZcVe8UDLLjj1ySYF828LATKKdxuakSZMvrDz54yiKPDYVfjdKqcX8Jky3BIA==",
-      "requires": {
-        "tslib": "2.3.0"
-      }
+      "version": "4.3.2",
+      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-4.3.2.tgz",
+      "integrity": "sha512-bIusJLS8c4DkIcdiK+s13HiQ/zjQQVgpNohtd8d94Y2DnJqgM1yjh/jpDb8DoL6hd7r8Awagw8e3qK/oLaWr3g=="
     }
   }
 }

+ 78 - 16
ui/src/views/largeScreen/index.vue

@@ -5,13 +5,45 @@
       <div class="btuGroup"><span class="topRightBtuBg topRightBtu" style="cursor: pointer;" @click="push()">后台管理</span>
       </div>
     </div>
-    <div id="fline" style="width: 900px;height: 450px"></div>
+    <div id="fline" style="float:left;width: 900px;height: 450px"></div>
+    <div style="float:right;top:50px;width: 900px;height: 450px">
+      <div>
+        <el-form ref="testform" :model="rtForm" label-width="250px" size="small">
+          <fieldset>
+            <legend>实时区</legend>
+            <el-form-item label="当前频率">
+              <el-input v-model="rtForm.fm" style="width: 240px" readonly></el-input>
+            </el-form-item>
+            <el-form-item label="当前有功">
+              <el-input v-model="rtForm.act" style="width: 240px" readonly></el-input>
+            </el-form-item>
+          </fieldset>
+        </el-form>
+      </div>
+      <el-form ref="testform" :model="testform" label-width="250px" size="small">
+        <fieldset>
+          <legend>调试设定值</legend>
+          <el-form-item label="模拟频率">
+            <el-input v-model="testform.fm" style="width: 240px"></el-input>
+          </el-form-item>
+          <el-form-item label="模拟有功">
+            <el-input v-model="testform.act" style="width: 240px"></el-input>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" @click="testSubmit">保存</el-button>
+          </el-form-item>
+        </fieldset>
+      </el-form>
+    </div>
   </div>
 </template>
 
 <script>
 // import electricityBar from './components/electricityBar'
 
+import {debounce} from "lodash";
+import store from "@/store";
+
 export default {
   name: "index",
   data() {
@@ -23,7 +55,6 @@ export default {
       datas:[],
       chart: null,
       time: '',
-      dialogTitle: '负载预测',
       dialogShow: false,
       componentName: 'loadForecasting',
       websock: null, //建立的连接
@@ -32,7 +63,15 @@ export default {
       timeoutObj: null, //心跳心跳倒计时
       serverTimeoutObj: null, //心跳倒计时
       timeoutnum: null, //断开 重连倒计时
-      fmOption:null
+      fmOption:null,
+      testform: {
+        fm: '',
+        act: ''
+      },
+      rtForm:{
+        fm: '',
+        act: ''
+      }
     }
   },
   mounted() {
@@ -86,18 +125,17 @@ export default {
             bottom: '8%',
             containLabel: true
         },
-        tooltip: {
-          trigger: 'axis',
-            formatter: function(params) {
-            var temp = "";
+        // tooltip: {
+        //   trigger: 'axis',
+        //     formatter: function(params) {
+        //     var temp = "";
             // if (params[0]!=undefined && params[1]!=undefined){
             //   temp = "时间:"+_this.$echarts.format.formatTime('hh:mm:ss.SSS', params[0].name) + "<br/>" + "有功:" + params[0].data[1]+ " MW<br/>" + "频率:" + params[0].data[1]+" Hz";
-              temp = "时间:"+_this.$echarts.format.formatTime('hh:mm:ss.SSS', params[0].name);
+            //   temp = "时间:"+_this.$echarts.format.formatTime('hh:mm:ss.SSS', params[0].name);
             // }
-
-            return temp;
-          },
-        },
+        //     return temp;
+        //   },
+        // },
         xAxis: {
           type: 'time',
             min: this.fmMinTime,
@@ -144,9 +182,9 @@ export default {
             splitLine: {show: false},
             position: 'right',
             name: '频率',
-            min: 48,
-            max: 51.5,
-            interval: 0.05,
+            min: 49.5,
+            max: 50.5,
+            interval: 0.1,
             axisLabel: {
               formatter: '{value} Hz'
             },
@@ -236,6 +274,12 @@ export default {
       // console.log("收到服务器信息",event.data);
       let data=event.data
       var tempFm = JSON.parse(data)
+      if (tempFm.f==-99){
+        tempFm.f=null
+      }
+      if (tempFm.activePower==-99){
+        tempFm.activePower=null
+      }
       // 存入频率数组
       this.fms.push({name: tempFm.time, value: [tempFm.time, tempFm.f]})
       this.activePower.push({name: tempFm.time, value: [tempFm.time, tempFm.activePower]})
@@ -254,11 +298,29 @@ export default {
         this.fmOption.series[0].data=this.activePower
         this.fmOption.series[1].data=this.fms
         this.chart.setOption(this.fmOption,true)
+
+        this.rtForm.fm = tempFm.f
+        this.rtForm.act = tempFm.activePower
     },
     websocketsend(msg) {
       //向服务器发送信息
       this.websock.send(msg);
-    }
+    },
+    testSubmit: debounce(async function () {
+      this.$refs["testform"].validate(async valid => {
+        if (valid) {
+          const param = {
+            fm: this.testform.fm,
+            act: this.testform.act
+          }
+          this.$axios.post('/frequencyController/testFmAct', this.$qs.stringify(param)).then((res) => {
+            this.$message.success('调试设定成功')
+          }).catch((error) => {
+
+          })
+        }
+      });
+    }, 1000)
   }
 }
 </script>