AgcDeviateService.java 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. package com.gyee.power.fitting.service.custom.agc;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.alibaba.fastjson.TypeReference;
  4. import com.gyee.power.fitting.common.feign.IDataAdapter;
  5. import com.gyee.power.fitting.mapper.AgcDeviateMapper;
  6. import com.gyee.power.fitting.model.AgcDeviateModel;
  7. import com.gyee.power.fitting.model.agc.AgcDeviateConfig;
  8. import com.gyee.power.fitting.model.agc.AgcDeviateTag;
  9. import com.gyee.power.fitting.model.agc.AiPoints;
  10. import com.gyee.power.fitting.model.agc.PointData;
  11. import org.springframework.core.annotation.Order;
  12. import org.springframework.core.env.Environment;
  13. import org.springframework.stereotype.Component;
  14. import javax.annotation.Resource;
  15. import java.io.File;
  16. import java.util.*;
  17. import java.util.stream.Collectors;
  18. /**
  19. * 读取数据库配置文件
  20. */
  21. @Order(0)
  22. @Component
  23. public class AgcDeviateService {
  24. /**
  25. * 是否是离线版本
  26. */
  27. private boolean isOffline;
  28. /**
  29. * 离线数据保存路径
  30. */
  31. private String filePathPower = "data\\power\\";
  32. /**
  33. * 文件读写
  34. */
  35. private FileService fileService;
  36. private Map<String, List<String>> files;
  37. /**
  38. * AGC信息缓存
  39. */
  40. private Map<String, AgcDeviateConfig> agcDeviateConfigMap= null;
  41. @Resource
  42. private IDataAdapter iDataAdapter;
  43. @Resource
  44. private AgcDeviateMapper agcDeviateMapper;
  45. // public AgcDeviateService( FileService fs, Environment env) {
  46. // fileService = fs;
  47. // agcDeviateConfigMap = new HashMap<>();
  48. //
  49. // isOffline = Boolean.TRUE.equals(env.getProperty("gyee.offline", boolean.class));
  50. // filePathPower = env.getProperty("gyee.file-path-power");
  51. //
  52. // AgcDeviateConfig[] adcs = null;
  53. // if (isOffline) {
  54. // adcs = fileService.getFromFile(filePathPower + "agc_info_net.json", AgcDeviateConfig[].class);
  55. // initFiles();
  56. // } else {
  57. // AgcDeviateModel adm = agcDeviateMapper.selectById("agc_info_net");
  58. // adcs = JSONObject.parseObject(adm.getValue(), AgcDeviateConfig[].class);
  59. // }
  60. // for (AgcDeviateConfig adc : adcs) {
  61. // agcDeviateConfigMap.put(adc.getId(), adc);
  62. // }
  63. // }
  64. private void initFiles() {
  65. files = new HashMap<>();
  66. File f = new File(filePathPower);
  67. File[] fs = f.listFiles();
  68. for (File v : fs) {
  69. if (v.isDirectory()) {
  70. continue;
  71. }
  72. String[] nm = v.getName().split(",");
  73. if (nm.length < 1) {
  74. continue;
  75. }
  76. String name = nm[0];
  77. if (!files.containsKey(name)) {
  78. files.put(name, new ArrayList<>());
  79. }
  80. files.get(name).add(v.getPath());
  81. }
  82. }
  83. /**
  84. * 获取agc曲线偏差分析需要的数据
  85. *
  86. * @param id 场站ID
  87. * @param startTs 开始时间戳
  88. * @param endTs 结束时间戳
  89. * @param interval 数据时间间隔
  90. * @return 分析数据
  91. */
  92. public List<AgcDeviateTag> getAgcDeviateTags(String id, long startTs, long endTs, int interval) {
  93. List<AgcDeviateTag> ladt = new ArrayList<>();
  94. List<AiPoints> laps = getAiPoints(id);
  95. if (laps == null) {
  96. return ladt;
  97. }
  98. for (AiPoints ap : laps) {
  99. AgcDeviateTag adt = new AgcDeviateTag();
  100. adt.setName(ap.getName());
  101. List<PointData> lpd = getPointData(ap, startTs, endTs, interval);
  102. adt.setValues(lpd);
  103. ladt.add(adt);
  104. }
  105. // 上限下限
  106. List<AgcDeviateTag> upperLowerLimits = getUpperLowerLimits(ladt, id);
  107. ladt.addAll(upperLowerLimits);
  108. return ladt;
  109. }
  110. private List<PointData> getPointData(AiPoints ap, long startTs, long endTs, int interval) {
  111. List<PointData> lpds = null;
  112. if (ap.getTag().contains(",")) {
  113. lpds = getMultiple(ap, startTs, endTs, interval);
  114. } else {
  115. lpds = iDataAdapter.getSnapValuesByKey(ap.getTag(), startTs, endTs, interval);
  116. }
  117. if (ap.getMultiplier() != 1) {
  118. for (PointData pd : lpds) {
  119. pd.setDoubleValue(pd.getDoubleValue() * ap.getMultiplier());
  120. }
  121. }
  122. return lpds;
  123. }
  124. /**
  125. * 获取多个标签点数值
  126. */
  127. private List<PointData> getMultiple(AiPoints ap, long startTs, long endTs, int interval) {
  128. String[] tags = ap.getTag().split(",");
  129. boolean isFirst = true;
  130. List<PointData> lpd = new ArrayList<>();
  131. for (String tag : tags) {
  132. if (tag.equals("")) {
  133. continue;
  134. }
  135. List<PointData> vals = iDataAdapter.getSnapValuesByKey(tag, startTs, endTs, interval);
  136. for (int i = 0; i < vals.size(); ++i) {
  137. if (isFirst) {
  138. lpd.addAll(vals);
  139. isFirst = false;
  140. break;
  141. } else {
  142. PointData pd = lpd.get(i);
  143. pd.setDoubleValue(vals.get(i).getDoubleValue() + pd.getDoubleValue());
  144. }
  145. }
  146. }
  147. return lpd;
  148. }
  149. /**
  150. * 获取上限下限
  151. */
  152. private List<AgcDeviateTag> getUpperLowerLimits(List<AgcDeviateTag> ladt, String id) {
  153. // 装机容量
  154. double capacity = getCapacity(id);
  155. // 偏差
  156. double deviation = capacity * 0.03;
  157. // 有功设定
  158. Optional<AgcDeviateTag> agcLimit = ladt.stream().filter(ad -> ad.getName().equals("有功设定限值")).findFirst();
  159. List<AgcDeviateTag> la = new ArrayList<>();
  160. if (!agcLimit.isPresent()) {
  161. return la;
  162. }
  163. AgcDeviateTag adtUper = new AgcDeviateTag();
  164. adtUper.setName("偏差上限");
  165. adtUper.setValues(new ArrayList<>());
  166. AgcDeviateTag adtLimt = new AgcDeviateTag();
  167. adtLimt.setName("偏差下限");
  168. adtLimt.setValues(new ArrayList<>());
  169. for (PointData pd : agcLimit.get().getValues()) {
  170. long ts = pd.getTs();
  171. PointData pdUper = new PointData();
  172. pdUper.setTs(ts);
  173. pdUper.setDoubleValue(pd.getDoubleValue() + deviation);
  174. PointData pdLimt = new PointData();
  175. pdLimt.setTs(ts);
  176. pdLimt.setDoubleValue(pd.getDoubleValue() - deviation);
  177. adtUper.getValues().add(pdUper);
  178. adtLimt.getValues().add(pdLimt);
  179. }
  180. la.add(adtUper);
  181. la.add(adtLimt);
  182. return la;
  183. }
  184. /**
  185. * 根据ID获取agc配置信息
  186. *
  187. * @param id 场站ID
  188. * @return 配置信息
  189. */
  190. private List<AiPoints> getAiPoints(String id) {
  191. if (!agcDeviateConfigMap.containsKey(id)) {
  192. return null;
  193. }
  194. AiPoints[] aiPoints = agcDeviateConfigMap.get(id).getAiPoints();
  195. return Arrays.stream(aiPoints).filter(ap -> ap.getName().contains("功") && !ap.getName().contains("预测")).collect(Collectors.toList());
  196. }
  197. private double getCapacity(String id) {
  198. if (!agcDeviateConfigMap.containsKey(id)) {
  199. return 0;
  200. }
  201. return agcDeviateConfigMap.get(id).getInstalledCapacity();
  202. }
  203. /**
  204. * 获取配置
  205. *
  206. * @return
  207. */
  208. public Object getConfig() {
  209. return agcDeviateConfigMap;
  210. }
  211. public List<AgcDeviateTag> getAgcDeviateTagsOffline(String id, long startTs, long endTs, int interval) {
  212. if (!files.containsKey(id)) {
  213. return new ArrayList<>();
  214. }
  215. List<String> ls = files.get(id);
  216. if (ls == null) {
  217. return new ArrayList<>();
  218. }
  219. int ran = (int) (Math.random() * ls.size());
  220. return fileService.getFromFile(ls.get(ran), new TypeReference<List<AgcDeviateTag>>() {
  221. });
  222. }
  223. }