|
@@ -0,0 +1,191 @@
|
|
|
+package com.gyee.power.fitting.service.custom.curve;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.gyee.power.fitting.common.feign.IDataAdapter;
|
|
|
+import com.gyee.power.fitting.model.agc.AgcDeviateConfig;
|
|
|
+import com.gyee.power.fitting.model.agc.AgcDeviateTag;
|
|
|
+import com.gyee.power.fitting.model.agc.AiPoints;
|
|
|
+import com.gyee.power.fitting.mapper.AgcDeviateMapper;
|
|
|
+import com.gyee.power.fitting.model.AgcDeviateModel;
|
|
|
+import com.gyee.power.fitting.model.agc.PointData;
|
|
|
+import org.springframework.core.annotation.Order;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 读取数据库配置文件
|
|
|
+ */
|
|
|
+@Order(0)
|
|
|
+@Component
|
|
|
+public class AgcDeviateService {
|
|
|
+ private final AgcDeviateMapper agcDeviateMapper;
|
|
|
+ /**
|
|
|
+ * AGC信息缓存
|
|
|
+ */
|
|
|
+ private Map<String, AgcDeviateConfig> agcDeviateConfigMap;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private IDataAdapter iDataAdapter;
|
|
|
+
|
|
|
+
|
|
|
+ public AgcDeviateService(AgcDeviateMapper agcDeviateMapper) {
|
|
|
+ this.agcDeviateMapper = agcDeviateMapper;
|
|
|
+ agcDeviateConfigMap = new HashMap<>();
|
|
|
+ AgcDeviateModel adm = agcDeviateMapper.selectById("agc_info_net");
|
|
|
+
|
|
|
+ AgcDeviateConfig[] adcs = JSON.parseObject(adm.getValue(), AgcDeviateConfig[].class);
|
|
|
+ for (AgcDeviateConfig adc : adcs) {
|
|
|
+ agcDeviateConfigMap.put(adc.getId(), adc);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取agc曲线偏差分析需要的数据
|
|
|
+ *
|
|
|
+ * @param id 场站ID
|
|
|
+ * @param startTs 开始时间戳
|
|
|
+ * @param endTs 结束时间戳
|
|
|
+ * @param interval 数据时间间隔
|
|
|
+ * @return 分析数据
|
|
|
+ */
|
|
|
+ public List<AgcDeviateTag> getAgcDeviateTags(String id, long startTs, long endTs, int interval) {
|
|
|
+ List<AgcDeviateTag> ladt = new ArrayList<>();
|
|
|
+ List<AiPoints> laps = getAiPoints(id);
|
|
|
+ if (laps == null) {
|
|
|
+ return ladt;
|
|
|
+ }
|
|
|
+ for (AiPoints ap : laps) {
|
|
|
+ AgcDeviateTag adt = new AgcDeviateTag();
|
|
|
+ adt.setName(ap.getName());
|
|
|
+ List<PointData> lpd = getPointData(ap, startTs, endTs, interval);
|
|
|
+ adt.setValues(lpd);
|
|
|
+ ladt.add(adt);
|
|
|
+ }
|
|
|
+ // 上限下限
|
|
|
+ List<AgcDeviateTag> upperLowerLimits = getUpperLowerLimits(ladt, id);
|
|
|
+ ladt.addAll(upperLowerLimits);
|
|
|
+ return ladt;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<PointData> getPointData(AiPoints ap, long startTs, long endTs, int interval) {
|
|
|
+ List<PointData> lpds = null;
|
|
|
+ if (ap.getTag().contains(",")) {
|
|
|
+ lpds = getMultiple(ap, startTs, endTs, interval);
|
|
|
+ } else {
|
|
|
+ lpds = iDataAdapter.getSnapValuesByKey(ap.getTag(), startTs, endTs, interval);
|
|
|
+ }
|
|
|
+ if (ap.getMultiplier() != 1) {
|
|
|
+ for (PointData pd : lpds) {
|
|
|
+ pd.setDoubleValue(pd.getDoubleValue() * ap.getMultiplier());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return lpds;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取多个标签点数值
|
|
|
+ */
|
|
|
+ private List<PointData> getMultiple(AiPoints ap, long startTs, long endTs, int interval) {
|
|
|
+ String[] tags = ap.getTag().split(",");
|
|
|
+ boolean isFirst = true;
|
|
|
+ List<PointData> lpd = new ArrayList<>();
|
|
|
+ for (String tag : tags) {
|
|
|
+ if (tag.equals("")) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ List<PointData> vals = iDataAdapter.getSnapValuesByKey(tag, startTs, endTs, interval);
|
|
|
+ for (int i = 0; i < vals.size(); ++i) {
|
|
|
+ if (isFirst) {
|
|
|
+ lpd.addAll(vals);
|
|
|
+ isFirst = false;
|
|
|
+ break;
|
|
|
+ } else {
|
|
|
+ PointData pd = lpd.get(i);
|
|
|
+ pd.setDoubleValue(vals.get(i).getDoubleValue() + pd.getDoubleValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return lpd;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取上限下限
|
|
|
+ */
|
|
|
+ private List<AgcDeviateTag> getUpperLowerLimits(List<AgcDeviateTag> ladt, String id) {
|
|
|
+ // 装机容量
|
|
|
+ double capacity = getCapacity(id);
|
|
|
+ // 偏差
|
|
|
+ double deviation = capacity * 0.03;
|
|
|
+ // 有功设定
|
|
|
+ Optional<AgcDeviateTag> agcLimit = ladt.stream().filter(ad -> ad.getName().equals("有功设定限值")).findFirst();
|
|
|
+
|
|
|
+ List<AgcDeviateTag> la = new ArrayList<>();
|
|
|
+ if (!agcLimit.isPresent()) {
|
|
|
+ return la;
|
|
|
+ }
|
|
|
+ AgcDeviateTag adtUper = new AgcDeviateTag();
|
|
|
+ adtUper.setName("偏差上限");
|
|
|
+ adtUper.setValues(new ArrayList<>());
|
|
|
+ AgcDeviateTag adtLimt = new AgcDeviateTag();
|
|
|
+ adtLimt.setName("偏差下限");
|
|
|
+ adtLimt.setValues(new ArrayList<>());
|
|
|
+
|
|
|
+ for (PointData pd : agcLimit.get().getValues()) {
|
|
|
+ long ts = pd.getTs();
|
|
|
+ PointData pdUper = new PointData();
|
|
|
+ pdUper.setTs(ts);
|
|
|
+ pdUper.setDoubleValue(pd.getDoubleValue() + deviation);
|
|
|
+ PointData pdLimt = new PointData();
|
|
|
+ pdLimt.setTs(ts);
|
|
|
+ pdLimt.setDoubleValue(pd.getDoubleValue() - deviation);
|
|
|
+ adtUper.getValues().add(pdUper);
|
|
|
+ adtLimt.getValues().add(pdLimt);
|
|
|
+ }
|
|
|
+ la.add(adtUper);
|
|
|
+ la.add(adtLimt);
|
|
|
+ return la;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据ID获取agc配置信息
|
|
|
+ *
|
|
|
+ * @param id 场站ID
|
|
|
+ * @return 配置信息
|
|
|
+ */
|
|
|
+ private List<AiPoints> getAiPoints(String id) {
|
|
|
+ if (!agcDeviateConfigMap.containsKey(id)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ AiPoints[] aiPoints = agcDeviateConfigMap.get(id).getAiPoints();
|
|
|
+ return Arrays.stream(aiPoints).filter(ap -> ap.getName().contains("功") && !ap.getName().contains("预测")).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ private double getCapacity(String id) {
|
|
|
+ if (!agcDeviateConfigMap.containsKey(id)) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return agcDeviateConfigMap.get(id).getInstalledCapacity();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取配置
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Object getConfig() {
|
|
|
+ return agcDeviateConfigMap;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|