package com.gyee.runeconomy.service.agc; import cn.hutool.core.lang.TypeReference; import com.gyee.runeconomy.config.GyeeConfig; import com.gyee.runeconomy.controller.agc.AgcDeviateTag; import com.gyee.runeconomy.controller.agc.AiPoints; import com.gyee.runeconomy.controller.agc.FileService; import com.gyee.runeconomy.init.CacheContext; import com.gyee.runeconomy.util.realtimesource.feign.IDataAdapter; import com.gyee.runeconomy.util.realtimesource.feign.RemoteServiceBuilder; import com.gyee.runeconomy.util.realtimesource.feign.TsDoubleTsData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.system.ApplicationHome; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; /** * 读取数据库配置文件 */ @Order(0) @Component public class AgcDeviateService { /** * 是否是离线版本 */ private boolean isOffline; /** * 离线数据保存路径 */ private String filePathPower = "data\\power\\"; public File jarF = null; { ApplicationHome h = new ApplicationHome(getClass()); jarF = h.getSource(); } /** * 文件读写 */ private FileService fileService; @Autowired private GyeeConfig config; @Resource private IDataAdapter iDataAdapter; @Autowired private RemoteServiceBuilder remoteService; /** * 获取agc曲线偏差分析需要的数据 * * @param id 场站ID * @param startTs 开始时间戳 * @param endTs 结束时间戳 * @param interval 数据时间间隔 * @return 分析数据 */ public List getAgcDeviateTags(String id, long startTs, long endTs, int interval) { List ladt = new ArrayList<>(); List laps = getAiPoints(id); if (laps == null) { return ladt; } for (AiPoints ap : laps) { AgcDeviateTag adt = new AgcDeviateTag(); adt.setName(ap.getName()); List lpd = getPointData(ap, startTs, endTs, interval); adt.setValues(lpd); ladt.add(adt); } // 上限下限 List upperLowerLimits = getUpperLowerLimits(ladt, id); ladt.addAll(upperLowerLimits); return ladt; } private List getPointData(AiPoints ap, long startTs, long endTs, int interval) { List lpds = null; if (ap.getTag().contains(",")) { lpds = getMultiple(ap, startTs, endTs, interval); } else { if (ap.getTag().startsWith("NEM")) { lpds = remoteService.taos().getHistorytsSnap(ap.getTag(), startTs, endTs, interval); } else { lpds = remoteService.adapterfd().getHistorytsSnap(ap.getTag(), startTs, endTs, interval); } } if (ap.getMultiplier() != 1) { for (TsDoubleTsData pd : lpds) { pd.setDoubleValue(pd.getDoubleValue() * ap.getMultiplier()); } } return lpds; } /** * 获取多个标签点数值 */ private List getMultiple(AiPoints ap, long startTs, long endTs, int interval) { String[] tags = ap.getTag().split(","); boolean isFirst = true; List lpd = new ArrayList<>(); for (String tag : tags) { if (tag.equals("")) { continue; } List vals = iDataAdapter.getHistorySnap(tag, startTs, endTs, interval); for (int i = 0; i < vals.size(); ++i) { if (isFirst) { lpd.addAll(vals); isFirst = false; break; } else { TsDoubleTsData pd = lpd.get(i); pd.setDoubleValue(vals.get(i).getDoubleValue() + pd.getDoubleValue()); } } } return lpd; } /** * 获取上限下限 */ private List getUpperLowerLimits(List ladt, String id) { // 装机容量 double capacity = getCapacity(id); // 偏差 double deviation = capacity * 0.03; // 有功设定 Optional agcLimit = ladt.stream().filter(ad -> ad.getName().equals("有功设定限值")).findFirst(); List 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 (TsDoubleTsData pd : agcLimit.get().getValues()) { long ts = pd.getTs(); TsDoubleTsData pdUper = new TsDoubleTsData(); pdUper.setTs(ts); pdUper.setDoubleValue(pd.getDoubleValue() * 1.03); TsDoubleTsData pdLimt = new TsDoubleTsData(); pdLimt.setTs(ts); pdLimt.setDoubleValue(pd.getDoubleValue() * 0.97); adtUper.getValues().add(pdUper); adtLimt.getValues().add(pdLimt); } la.add(adtUper); la.add(adtLimt); return la; } /** * 根据ID获取agc配置信息 * * @param id 场站ID * @return 配置信息 */ private List getAiPoints(String id) { if (!CacheContext.agcDeviateConfigMap.containsKey(id)) { return null; } AiPoints[] aiPoints = CacheContext.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 (!CacheContext.agcDeviateConfigMap.containsKey(id)) { return 0; } return CacheContext.agcDeviateConfigMap.get(id).getInstalledCapacity(); } /** * 获取配置 * * @return */ public Object getConfig() { return CacheContext.agcDeviateConfigMap; } public List getAgcDeviateTagsOffline(String id, long startTs, long endTs, int interval) { if (!CacheContext.files.containsKey(id)) { return new ArrayList<>(); } List ls = CacheContext.files.get(id); if (ls == null) { return new ArrayList<>(); } int ran = (int) (Math.random() * ls.size()); return fileService.getFromFile(ls.get(ran), new TypeReference>() { }); } }