VppUnMessageBuilder.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. package com.usky.vpp.util;
  2. import com.usky.vpp.config.VppUnProperties;
  3. import com.usky.vpp.domain.VppResourcePoint;
  4. import com.usky.vpp.domain.VppSite;
  5. import org.springframework.util.StringUtils;
  6. import java.math.BigDecimal;
  7. import java.time.LocalDateTime;
  8. import java.time.format.DateTimeFormatter;
  9. import java.util.ArrayList;
  10. import java.util.HashMap;
  11. import java.util.LinkedHashMap;
  12. import java.util.List;
  13. import java.util.Map;
  14. import java.util.UUID;
  15. /**
  16. * 构造运管平台标准响应报文(联调 JSON 实例)
  17. */
  18. public final class VppUnMessageBuilder {
  19. private static final DateTimeFormatter CREATED_DATE_TIME =
  20. DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  21. private static final DateTimeFormatter MOMENT_DATE_TIME = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
  22. private VppUnMessageBuilder() {
  23. }
  24. public static Map<String, Object> buildTokenRequest(VppUnProperties properties) {
  25. return buildBaseRequest("TokenRequest", properties);
  26. }
  27. public static Map<String, Object> buildPollRequest(VppUnProperties properties) {
  28. return buildBaseRequest("Poll", properties);
  29. }
  30. public static Map<String, Object> buildCreateRegistrationRequest(VppUnProperties properties) {
  31. Map<String, Object> req = buildBaseRequest("CreateRegistrationRequest", properties);
  32. req.put("dnName", properties.getDnName());
  33. if (StringUtils.hasText(properties.getRegistrationId())) {
  34. req.put("registrationID", properties.getRegistrationId());
  35. }
  36. req.put("reportOnly", false);
  37. req.put("pullMode", true);
  38. req.put("signature", false);
  39. req.put("transport", "REST");
  40. req.put("transportAddress", properties.getTransportAddress());
  41. return req;
  42. }
  43. public static Map<String, Object> buildCreateOptRequest(String eventId, String optType,
  44. List<Map<String, Object>> list,
  45. VppUnProperties properties) {
  46. Map<String, Object> req = buildBaseRequest("CreateOptRequest", properties);
  47. req.put("eventID", eventId);
  48. req.put("optType", optType);
  49. req.put("createdDateTime", CREATED_DATE_TIME.format(LocalDateTime.now()));
  50. req.put("priceDownCoeff", properties.getPriceDownCoeff());
  51. if (list != null) {
  52. req.put("list", list);
  53. }
  54. return req;
  55. }
  56. public static Map<String, Object> buildCreateCqRequest(String eventId, String optType,
  57. List<Map<String, Object>> list,
  58. VppUnProperties properties) {
  59. Map<String, Object> req = buildBaseRequest("CreateCqRequest", properties);
  60. req.put("eventID", eventId);
  61. req.put("optType", optType != null ? optType : "optIn");
  62. req.put("createdDateTime", CREATED_DATE_TIME.format(LocalDateTime.now()));
  63. req.put("priceDownCoeff", properties.getPriceDownCoeff());
  64. if (list != null) {
  65. req.put("list", list);
  66. }
  67. return req;
  68. }
  69. public static Map<String, Object> buildCreateReportResponse(Map<String, Object> request, VppUnProperties properties) {
  70. Map<String, Object> resp = new LinkedHashMap<>();
  71. if (request != null) {
  72. resp.put("requestID", request.get("requestID"));
  73. }
  74. resp.put("root", "CreateReportResponse");
  75. resp.put("version", 1);
  76. resp.put("code", 200);
  77. resp.put("description", "ok");
  78. if (resp.get("requestID") == null) {
  79. resp.put("requestID", UUID.randomUUID().toString());
  80. }
  81. resp.put("dnID", properties.getDnId());
  82. Map<String, Object> pendingReports = new LinkedHashMap<>();
  83. List<String> reportRequestIds = new ArrayList<>();
  84. reportRequestIds.add("MetaDataReport");
  85. pendingReports.put("reportRequestID", reportRequestIds);
  86. resp.put("pendingReports", pendingReports);
  87. return resp;
  88. }
  89. /**
  90. * 构造 RegisterReportRequest:虚拟电厂量测点(含负荷预测)+ 站点/资源点有功功率(kW)。
  91. */
  92. public static Map<String, Object> buildRegisterReportRequest(VppUnProperties properties,
  93. List<VppSite> sites,
  94. List<VppResourcePoint> resources,
  95. Map<Long, String> deviceUnResourceIdMap) {
  96. Map<String, Object> req = buildBaseRequest("RegisterReportRequest", properties);
  97. req.put("reportRequestID", "MetaDataReport");
  98. List<Map<String, Object>> reports = new ArrayList<>();
  99. String createdDateTime = CREATED_DATE_TIME.format(LocalDateTime.now());
  100. for (VppUnRegisterReportIndex.Entry entry : VppUnRegisterReportIndex.buildRegisterEntries(
  101. properties, sites, resources, deviceUnResourceIdMap)) {
  102. String resourceId = resolveRegisterResourceId(entry, properties, deviceUnResourceIdMap);
  103. reports.add(buildVppMetadataReportItem(entry.getRid(), entry.getMetric(), resourceId, createdDateTime));
  104. }
  105. req.put("report", reports);
  106. return req;
  107. }
  108. private static String resolveRegisterResourceId(VppUnRegisterReportIndex.Entry entry,
  109. VppUnProperties properties,
  110. Map<Long, String> deviceUnResourceIdMap) {
  111. if (entry.getScope() == VppUnRegisterReportIndex.Scope.SITE) {
  112. return entry.getSite().getUnResourceId();
  113. }
  114. if (entry.getScope() == VppUnRegisterReportIndex.Scope.RESOURCE) {
  115. return deviceUnResourceIdMap.get(entry.getResource().getDeviceId());
  116. }
  117. return properties.getDnId();
  118. }
  119. public static Map<String, Object> buildIntervalDataReportRequest(VppUnProperties properties,
  120. Map<String, Object> createReportRequest,
  121. List<Map<String, Object>> pointCurveData,
  122. LocalDateTime reportTime) {
  123. Map<String, Object> req = buildBaseRequest("IntervalDataReportRequest", properties);
  124. req.put("reportRequestID", resolveReportRequestIdFromPoll(createReportRequest, "IntervalDataReport"));
  125. LocalDateTime createdAt = reportTime != null ? reportTime : LocalDateTime.now();
  126. req.put("createdDateTime", MOMENT_DATE_TIME.format(createdAt));
  127. req.put("pointCurveData", pointCurveData != null ? pointCurveData : new ArrayList<>());
  128. return req;
  129. }
  130. public static Map<String, Object> buildIntervalCurveDataEntry(int rid, List<Map<String, Object>> values) {
  131. Map<String, Object> entry = new LinkedHashMap<>();
  132. entry.put("rID", rid);
  133. Map<String, Object> irregular = new LinkedHashMap<>();
  134. irregular.put("values", values != null ? values : new ArrayList<>());
  135. entry.put("irregular", irregular);
  136. return entry;
  137. }
  138. public static Map<String, Object> buildIntervalCurveValue(BigDecimal value,
  139. LocalDateTime timestamp,
  140. String quality) {
  141. Map<String, Object> point = new LinkedHashMap<>();
  142. point.put("value", value != null ? value : BigDecimal.ZERO);
  143. point.put("timestamp", MOMENT_DATE_TIME.format(timestamp != null ? timestamp : LocalDateTime.now()));
  144. point.put("quality", StringUtils.hasText(quality) ? quality : "good");
  145. return point;
  146. }
  147. public static Map<String, Object> buildMomentDataReportRequest(VppUnProperties properties,
  148. Map<String, Object> createReportRequest,
  149. List<Map<String, Object>> pointData,
  150. LocalDateTime reportTime) {
  151. Map<String, Object> req = buildBaseRequest("MomentDataReportRequest", properties);
  152. req.put("reportRequestID", resolveReportRequestIdFromPoll(createReportRequest, "MomentDataReport"));
  153. LocalDateTime createdAt = reportTime != null ? reportTime : LocalDateTime.now();
  154. req.put("createdDateTime", MOMENT_DATE_TIME.format(createdAt));
  155. req.put("pointData", pointData != null ? pointData : new ArrayList<>());
  156. return req;
  157. }
  158. public static Map<String, Object> buildMomentDataPoint(int rid,
  159. BigDecimal value,
  160. LocalDateTime timestamp,
  161. String quality) {
  162. Map<String, Object> point = new LinkedHashMap<>();
  163. point.put("rID", rid);
  164. point.put("value", value != null ? value : BigDecimal.ZERO);
  165. point.put("timestamp", MOMENT_DATE_TIME.format(timestamp != null ? timestamp : LocalDateTime.now()));
  166. point.put("quality", StringUtils.hasText(quality) ? quality : "good");
  167. return point;
  168. }
  169. public static Map<String, Object> buildLoadForecastReportRequest(Map<String, Object> createReportRequest,
  170. List<VppResourcePoint> resources,
  171. Map<Long, VppSite> siteMap,
  172. VppUnProperties properties) {
  173. Map<String, Object> req = buildBaseRequest("LoadForecastReportRequest", properties);
  174. req.put("reportRequestID", resolveReportRequestIdFromPoll(createReportRequest, "LoadForecastReport"));
  175. req.put("createdDateTime", CREATED_DATE_TIME.format(LocalDateTime.now()));
  176. req.put("pointData", buildPointData(resources, siteMap, properties));
  177. return req;
  178. }
  179. public static Map<String, Object> buildRegulateForecastReportRequest(Map<String, Object> createReportRequest,
  180. List<VppResourcePoint> resources,
  181. Map<Long, VppSite> siteMap,
  182. VppUnProperties properties) {
  183. Map<String, Object> req = buildBaseRequest("RegulateForecastReportRequest", properties);
  184. req.put("reportRequestID", resolveReportRequestIdFromPoll(createReportRequest, "RegulateForecastReport"));
  185. req.put("createdDateTime", CREATED_DATE_TIME.format(LocalDateTime.now()));
  186. req.put("pointData", buildPointData(resources, siteMap, properties));
  187. return req;
  188. }
  189. private static Map<String, Object> buildVppMetadataReportItem(int rid,
  190. VppUnRegisterMetricDefinitions.RegisterMetric metric,
  191. String resourceId,
  192. String createdDateTime) {
  193. Map<String, Object> report = new LinkedHashMap<>();
  194. report.put("createdDateTime", createdDateTime);
  195. Map<String, Object> description = new LinkedHashMap<>();
  196. description.put("rID", rid);
  197. Map<String, Object> metricBody = new LinkedHashMap<>();
  198. metricBody.put("metricName", metric.getMetricName());
  199. if (StringUtils.hasText(metric.getMultiplier())) {
  200. metricBody.put("multiplier", metric.getMultiplier());
  201. }
  202. metricBody.put("symbol", metric.getSymbol());
  203. description.put("metric", metricBody);
  204. Map<String, Object> dataSource = new LinkedHashMap<>();
  205. dataSource.put("resourceID", java.util.Collections.singletonList(resourceId));
  206. description.put("reportDataSource", dataSource);
  207. report.put("reportDescription", description);
  208. return report;
  209. }
  210. private static List<Map<String, Object>> buildPointData(List<VppResourcePoint> resources,
  211. Map<Long, VppSite> siteMap,
  212. VppUnProperties properties) {
  213. List<Map<String, Object>> pointData = new ArrayList<>();
  214. if (resources == null || resources.isEmpty()) {
  215. Map<String, Object> point = new LinkedHashMap<>();
  216. point.put("resourceID", properties.getDnId());
  217. point.put("value", "0");
  218. point.put("timestamp", CREATED_DATE_TIME.format(LocalDateTime.now()));
  219. pointData.add(point);
  220. return pointData;
  221. }
  222. String timestamp = CREATED_DATE_TIME.format(LocalDateTime.now());
  223. for (VppResourcePoint resource : resources) {
  224. Map<String, Object> point = new LinkedHashMap<>();
  225. VppSite site = siteMap != null ? siteMap.get(resource.getSiteId()) : null;
  226. point.put("resourceID", resolveUnResourceId(resource, site, properties));
  227. BigDecimal value = resource.getMaxUpKw() != null ? resource.getMaxUpKw() : BigDecimal.ZERO;
  228. point.put("value", value.stripTrailingZeros().toPlainString());
  229. point.put("timestamp", timestamp);
  230. pointData.add(point);
  231. }
  232. return pointData;
  233. }
  234. private static String resolveUnResourceId(VppResourcePoint resource, VppSite site, VppUnProperties properties) {
  235. if (site != null && StringUtils.hasText(site.getUnResourceId())) {
  236. return site.getUnResourceId();
  237. }
  238. if (StringUtils.hasText(resource.getResourceCode())) {
  239. return resource.getResourceCode();
  240. }
  241. return properties.getDnId();
  242. }
  243. @SuppressWarnings("unchecked")
  244. private static String resolveReportRequestIdFromPoll(Map<String, Object> createReportRequest, String fallback) {
  245. if (createReportRequest == null) {
  246. return fallback;
  247. }
  248. Object reportRequest = createReportRequest.get("reportRequest");
  249. if (reportRequest instanceof List && !((List<?>) reportRequest).isEmpty()) {
  250. Object first = ((List<?>) reportRequest).get(0);
  251. if (first instanceof Map) {
  252. String id = VppUnPayloadHelper.getString((Map<String, Object>) first,
  253. "reportRequestID", "reportRequestId");
  254. if (StringUtils.hasText(id)) {
  255. return id;
  256. }
  257. }
  258. }
  259. String id = VppUnPayloadHelper.getString(createReportRequest, "reportRequestID", "reportRequestId");
  260. return StringUtils.hasText(id) ? id : fallback;
  261. }
  262. public static Map<String, Object> buildOptListItem(String account, BigDecimal loadKw, String needZk) {
  263. Map<String, Object> item = new LinkedHashMap<>();
  264. item.put("account", account);
  265. item.put("load", loadKw != null ? loadKw.stripTrailingZeros().toPlainString() : "0");
  266. if (StringUtils.hasText(needZk)) {
  267. item.put("needzk", needZk);
  268. }
  269. return item;
  270. }
  271. private static Map<String, Object> buildBaseRequest(String root, VppUnProperties properties) {
  272. Map<String, Object> req = new LinkedHashMap<>();
  273. req.put("root", root);
  274. req.put("version", 1);
  275. req.put("requestID", UUID.randomUUID().toString());
  276. req.put("dnID", properties.getDnId());
  277. return req;
  278. }
  279. public static Map<String, Object> buildCreateOptResponse(Map<String, Object> request, VppUnProperties properties) {
  280. Map<String, Object> resp = copyRequestAsResponse(request, "CreateOptResponse");
  281. fillCommon(resp, properties);
  282. resp.put("code", 200);
  283. resp.put("description", "ok");
  284. return resp;
  285. }
  286. public static Map<String, Object> buildCreateCqResponse(Map<String, Object> request, VppUnProperties properties) {
  287. Map<String, Object> resp = copyRequestAsResponse(request, "CreateCqResponse");
  288. fillCommon(resp, properties);
  289. resp.put("code", 200);
  290. resp.put("description", "ok");
  291. return resp;
  292. }
  293. public static Map<String, Object> buildCreateEventResponse(String eventId, String requestId,
  294. String optType, VppUnProperties properties) {
  295. Map<String, Object> resp = new LinkedHashMap<>();
  296. resp.put("root", "CreateEventResponse");
  297. resp.put("version", 1);
  298. resp.put("code", 200);
  299. resp.put("description", "ok");
  300. resp.put("requestID", requestId != null ? requestId : UUID.randomUUID().toString());
  301. resp.put("dnID", properties.getDnId());
  302. Map<String, Object> eventResponse = new LinkedHashMap<>();
  303. eventResponse.put("optType", optType != null ? optType : "optIn");
  304. eventResponse.put("code", 200);
  305. eventResponse.put("description", "ok");
  306. eventResponse.put("requestID", UUID.randomUUID().toString());
  307. Map<String, Object> qualifiedEventId = new HashMap<>();
  308. qualifiedEventId.put("eventID", eventId);
  309. qualifiedEventId.put("modificationNumber", 0);
  310. eventResponse.put("qualifiedEventID", qualifiedEventId);
  311. List<Map<String, Object>> eventResponses = new ArrayList<>();
  312. eventResponses.add(eventResponse);
  313. resp.put("eventResponses", eventResponses);
  314. return resp;
  315. }
  316. private static Map<String, Object> copyRequestAsResponse(Map<String, Object> request, String root) {
  317. Map<String, Object> resp = new LinkedHashMap<>();
  318. if (request != null) {
  319. resp.putAll(request);
  320. }
  321. resp.put("root", root);
  322. resp.put("version", request != null && request.get("version") != null ? request.get("version") : 1);
  323. return resp;
  324. }
  325. private static void fillCommon(Map<String, Object> resp, VppUnProperties properties) {
  326. if (resp.get("requestID") == null) {
  327. resp.put("requestID", UUID.randomUUID().toString());
  328. }
  329. resp.put("dnID", properties.getDnId());
  330. }
  331. }