package com.gyee.power.fitting.service.custom.agc; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import com.gyee.power.fitting.common.feign.IDataAdapter; import com.gyee.power.fitting.mapper.AgcDeviateMapper; import com.gyee.power.fitting.model.AgcDeviateModel; 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.model.agc.PointData; import org.springframework.core.annotation.Order; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.io.File; import java.util.*; import java.util.stream.Collectors; /** * 读取数据库配置文件 */ @Order(0) @Component public class AgcDeviateService { /** * 是否是离线版本 */ private boolean isOffline; /** * 离线数据保存路径 */ private String filePathPower = "data\\power\\"; /** * 文件读写 */ private FileService fileService; private Map> files; /** * AGC信息缓存 */ private Map agcDeviateConfigMap= null; @Resource private IDataAdapter iDataAdapter; @Resource private AgcDeviateMapper agcDeviateMapper; // public AgcDeviateService( FileService fs, Environment env) { // fileService = fs; // agcDeviateConfigMap = new HashMap<>(); // // isOffline = Boolean.TRUE.equals(env.getProperty("gyee.offline", boolean.class)); // filePathPower = env.getProperty("gyee.file-path-power"); // // AgcDeviateConfig[] adcs = null; // if (isOffline) { // adcs = fileService.getFromFile(filePathPower + "agc_info_net.json", AgcDeviateConfig[].class); // initFiles(); // } else { // AgcDeviateModel adm = agcDeviateMapper.selectById("agc_info_net"); // adcs = JSONObject.parseObject(adm.getValue(), AgcDeviateConfig[].class); // } // for (AgcDeviateConfig adc : adcs) { // agcDeviateConfigMap.put(adc.getId(), adc); // } // } private void initFiles() { files = new HashMap<>(); File f = new File(filePathPower); File[] fs = f.listFiles(); for (File v : fs) { if (v.isDirectory()) { continue; } String[] nm = v.getName().split(","); if (nm.length < 1) { continue; } String name = nm[0]; if (!files.containsKey(name)) { files.put(name, new ArrayList<>()); } files.get(name).add(v.getPath()); } } /** * 获取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 { 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 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.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 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 (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 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; } public List getAgcDeviateTagsOffline(String id, long startTs, long endTs, int interval) { if (!files.containsKey(id)) { return new ArrayList<>(); } List ls = files.get(id); if (ls == null) { return new ArrayList<>(); } int ran = (int) (Math.random() * ls.size()); return fileService.getFromFile(ls.get(ran), new TypeReference>() { }); } }