|
|
@@ -4,22 +4,38 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.usky.vpp.client.VppUnClient;
|
|
|
import com.usky.vpp.config.VppUnProperties;
|
|
|
import com.usky.vpp.config.VppUnPropertiesRegistry;
|
|
|
+import com.usky.vpp.config.VppUnTenantContext;
|
|
|
+import com.usky.vpp.domain.VppDevice;
|
|
|
import com.usky.vpp.domain.VppResourcePoint;
|
|
|
import com.usky.vpp.domain.VppSite;
|
|
|
+import com.usky.vpp.mapper.VppDeviceMapper;
|
|
|
import com.usky.vpp.mapper.VppResourcePointMapper;
|
|
|
+import com.usky.vpp.mapper.VppSiteMapper;
|
|
|
+import com.usky.vpp.service.VppTsdbQueryService;
|
|
|
import com.usky.vpp.service.VppUnReportService;
|
|
|
-import com.usky.vpp.util.VppAuditHelper;
|
|
|
-import com.usky.vpp.util.VppSiteResourceHelper;
|
|
|
-import com.usky.vpp.util.VppUnMessageBuilder;
|
|
|
-import com.usky.vpp.util.VppUnPayloadHelper;
|
|
|
+import com.usky.vpp.constant.VppDrEventStatus;
|
|
|
+import com.usky.vpp.domain.VppDrEvent;
|
|
|
+import com.usky.vpp.mapper.VppDrEventMapper;
|
|
|
+import com.usky.vpp.util.*;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.util.StringUtils;
|
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.LinkedHashSet;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
@Service
|
|
|
public class VppUnReportServiceImpl implements VppUnReportService {
|
|
|
@@ -33,7 +49,15 @@ public class VppUnReportServiceImpl implements VppUnReportService {
|
|
|
@Autowired
|
|
|
private VppResourcePointMapper resourcePointMapper;
|
|
|
@Autowired
|
|
|
+ private VppSiteMapper siteMapper;
|
|
|
+ @Autowired
|
|
|
+ private VppDeviceMapper deviceMapper;
|
|
|
+ @Autowired
|
|
|
private VppSiteResourceHelper siteResourceHelper;
|
|
|
+ @Autowired
|
|
|
+ private VppTsdbQueryService vppTsdbQueryService;
|
|
|
+ @Autowired
|
|
|
+ private VppDrEventMapper drEventMapper;
|
|
|
|
|
|
@Override
|
|
|
public void handleCreateReportRequest(Map<String, Object> createReportRequest) {
|
|
|
@@ -52,13 +76,13 @@ public class VppUnReportServiceImpl implements VppUnReportService {
|
|
|
}
|
|
|
switch (reportRequestId) {
|
|
|
case "MetaDataReport":
|
|
|
- submitRegisterReport();
|
|
|
+ doSubmitRegisterReport();
|
|
|
break;
|
|
|
case "IntervalDataReport":
|
|
|
- submitIntervalDataReport(createReportRequest);
|
|
|
+ doSubmitIntervalDataReport(createReportRequest);
|
|
|
break;
|
|
|
case "MomentDataReport":
|
|
|
- submitMomentDataReport(createReportRequest);
|
|
|
+ doSubmitMomentDataReport(createReportRequest);
|
|
|
break;
|
|
|
// case "LoadForecastReport":
|
|
|
// submitLoadForecastReport(createReportRequest);
|
|
|
@@ -72,33 +96,123 @@ public class VppUnReportServiceImpl implements VppUnReportService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void submitRegisterReport() {
|
|
|
+ @Override
|
|
|
+ public void submitRegisterReport() {
|
|
|
VppUnProperties properties = propertiesRegistry.getCurrent();
|
|
|
+ if (!properties.isOutboundActive()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ doSubmitRegisterReport();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void doSubmitRegisterReport() {
|
|
|
+ VppUnProperties properties = propertiesRegistry.getCurrent();
|
|
|
+ Integer tenantId = VppUnTenantContext.resolveTenantId();
|
|
|
+ List<VppSite> sites = listActiveSites(tenantId);
|
|
|
List<VppResourcePoint> resources = listActiveResources(false);
|
|
|
- Map<Long, VppSite> siteMap = siteResourceHelper.loadSiteMap(resources);
|
|
|
- Map<String, Object> request = VppUnMessageBuilder.buildRegisterReportRequest(resources, siteMap, properties);
|
|
|
+ Map<Long, String> deviceUnResourceIdMap = loadDeviceUnResourceIdMap(resources);
|
|
|
+ Map<String, Object> request = VppUnMessageBuilder.buildRegisterReportRequest(
|
|
|
+ properties, sites, resources, deviceUnResourceIdMap);
|
|
|
unClient.post("RegisterReportRequest", request, true);
|
|
|
- log.info("已提交 RegisterReportRequest");
|
|
|
+ long siteMetricCount = sites.stream()
|
|
|
+ .filter(site -> site != null && StringUtils.hasText(site.getUnResourceId()))
|
|
|
+ .count();
|
|
|
+ long resourceMetricCount = resources.stream()
|
|
|
+ .filter(resource -> resource != null
|
|
|
+ && resource.getDeviceId() != null
|
|
|
+ && StringUtils.hasText(deviceUnResourceIdMap.get(resource.getDeviceId())))
|
|
|
+ .count();
|
|
|
+ log.info("已提交 RegisterReportRequest,虚拟电厂量测点={},站点量测点={},资源点量测点={}",
|
|
|
+ VppUnRegisterMetricDefinitions.VPP_REGISTER_METRICS.size(), siteMetricCount, resourceMetricCount);
|
|
|
}
|
|
|
|
|
|
- private void submitIntervalDataReport(Map<String, Object> createReportRequest) {
|
|
|
+ @Override
|
|
|
+ public void submitIntervalDataReport(Map<String, Object> createReportRequest) {
|
|
|
VppUnProperties properties = propertiesRegistry.getCurrent();
|
|
|
- List<VppResourcePoint> resources = listActiveResources(true);
|
|
|
- Map<Long, VppSite> siteMap = siteResourceHelper.loadSiteMap(resources);
|
|
|
+ if (!properties.isOutboundActive()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ doSubmitIntervalDataReport(createReportRequest);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void doSubmitIntervalDataReport(Map<String, Object> createReportRequest) {
|
|
|
+ VppUnProperties properties = propertiesRegistry.getCurrent();
|
|
|
+ Integer tenantId = VppUnTenantContext.resolveTenantId();
|
|
|
+ List<VppSite> sites = listActiveSites(tenantId);
|
|
|
+ List<VppResourcePoint> resources = listActiveResources(false);
|
|
|
+ List<VppResourcePoint> peakResources = listActiveResources(true);
|
|
|
+ Map<Long, String> deviceUnResourceIdMap = loadDeviceUnResourceIdMap(resources);
|
|
|
+ Map<Long, VppDevice> deviceMap = loadDeviceMap(resources);
|
|
|
+ Map<Long, List<String>> peakDeviceUuidsBySite = groupPeakDeviceUuidsBySite(peakResources, deviceMap);
|
|
|
+ List<String> tenantPeakDeviceUuids = collectDeviceUuids(peakResources, deviceMap);
|
|
|
+
|
|
|
+ LocalDate forecastDate = VppUnIntervalDataHelper.resolveForecastDate();
|
|
|
+ boolean workday = VppBaselineHelper.isWorkdayResponse(forecastDate);
|
|
|
+ int requiredCount = workday
|
|
|
+ ? VppBaselineHelper.WEEKDAY_REFERENCE_COUNT
|
|
|
+ : VppBaselineHelper.NON_WEEKDAY_REFERENCE_COUNT;
|
|
|
+ List<LocalDate> referenceDates = VppBaselineHelper.selectReferenceDates(
|
|
|
+ forecastDate, workday, loadResponseHistoryDates(), requiredCount, LocalDate.now());
|
|
|
+
|
|
|
+ LocalDateTime reportTime = LocalDateTime.now();
|
|
|
+ List<VppUnRegisterReportIndex.Entry> entries = VppUnRegisterReportIndex.buildEntries(
|
|
|
+ properties, sites, resources, deviceUnResourceIdMap);
|
|
|
+ List<Map<String, Object>> pointCurveData = new ArrayList<>(entries.size());
|
|
|
+ for (VppUnRegisterReportIndex.Entry entry : entries) {
|
|
|
+ List<String> deviceUuids = resolveMomentDataDeviceUuids(
|
|
|
+ entry, tenantPeakDeviceUuids, peakDeviceUuidsBySite, deviceMap);
|
|
|
+ List<Map<String, Object>> curveValues = VppUnIntervalDataHelper.buildForecastCurveValues(
|
|
|
+ vppTsdbQueryService, deviceUuids, referenceDates, forecastDate, entry.getMetric());
|
|
|
+ pointCurveData.add(VppUnMessageBuilder.buildIntervalCurveDataEntry(entry.getRid(), curveValues));
|
|
|
+ }
|
|
|
+
|
|
|
Map<String, Object> request = VppUnMessageBuilder.buildIntervalDataReportRequest(
|
|
|
- createReportRequest, resources, siteMap, properties);
|
|
|
+ properties, createReportRequest, pointCurveData, reportTime);
|
|
|
unClient.post("IntervalDataReportRequest", request, true);
|
|
|
- log.info("已提交 IntervalDataReportRequest");
|
|
|
+ log.info("已提交 IntervalDataReportRequest,pointCurveData={},预测日={},参考日数={}",
|
|
|
+ pointCurveData.size(), forecastDate, referenceDates.size());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void submitMomentDataReport() {
|
|
|
+ VppUnProperties properties = propertiesRegistry.getCurrent();
|
|
|
+ if (!properties.isOutboundActive()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ doSubmitMomentDataReport(null);
|
|
|
}
|
|
|
|
|
|
- private void submitMomentDataReport(Map<String, Object> createReportRequest) {
|
|
|
+ private void doSubmitMomentDataReport(Map<String, Object> createReportRequest) {
|
|
|
VppUnProperties properties = propertiesRegistry.getCurrent();
|
|
|
- List<VppResourcePoint> resources = listActiveResources(true);
|
|
|
- Map<Long, VppSite> siteMap = siteResourceHelper.loadSiteMap(resources);
|
|
|
+ Integer tenantId = VppUnTenantContext.resolveTenantId();
|
|
|
+ List<VppSite> sites = listActiveSites(tenantId);
|
|
|
+ List<VppResourcePoint> resources = listActiveResources(false);
|
|
|
+ List<VppResourcePoint> peakResources = listActiveResources(true);
|
|
|
+ Map<Long, String> deviceUnResourceIdMap = loadDeviceUnResourceIdMap(resources);
|
|
|
+ Map<Long, VppDevice> deviceMap = loadDeviceMap(resources);
|
|
|
+ Map<Long, List<String>> peakDeviceUuidsBySite = groupPeakDeviceUuidsBySite(peakResources, deviceMap);
|
|
|
+ List<String> tenantPeakDeviceUuids = collectDeviceUuids(peakResources, deviceMap);
|
|
|
+
|
|
|
+ LocalDateTime windowEnd = VppUnMomentDataHelper.resolveWindowEnd(LocalDateTime.now());
|
|
|
+ LocalDateTime windowStart = VppUnMomentDataHelper.resolveWindowStart(windowEnd);
|
|
|
+
|
|
|
+ List<VppUnRegisterReportIndex.Entry> entries = VppUnRegisterReportIndex.buildEntries(
|
|
|
+ properties, sites, resources, deviceUnResourceIdMap);
|
|
|
+ List<Map<String, Object>> pointData = new ArrayList<>(entries.size());
|
|
|
+ for (VppUnRegisterReportIndex.Entry entry : entries) {
|
|
|
+ List<String> deviceUuids = resolveMomentDataDeviceUuids(
|
|
|
+ entry, tenantPeakDeviceUuids, peakDeviceUuidsBySite, deviceMap);
|
|
|
+ BigDecimal value = VppUnMomentDataHelper.aggregateMetricValue(
|
|
|
+ vppTsdbQueryService, deviceUuids, windowStart, windowEnd, entry.getMetric());
|
|
|
+ pointData.add(VppUnMessageBuilder.buildMomentDataPoint(
|
|
|
+ entry.getRid(), value, windowEnd, "good"));
|
|
|
+ }
|
|
|
+
|
|
|
Map<String, Object> request = VppUnMessageBuilder.buildMomentDataReportRequest(
|
|
|
- createReportRequest, resources, siteMap, properties);
|
|
|
+ properties, createReportRequest, pointData, windowEnd);
|
|
|
unClient.post("MomentDataReportRequest", request, true);
|
|
|
- log.info("已提交 MomentDataReportRequest");
|
|
|
+ log.info("已提交 MomentDataReportRequest,pointData={},窗口 {} ~ {}",
|
|
|
+ pointData.size(), windowStart, windowEnd);
|
|
|
}
|
|
|
|
|
|
private void submitLoadForecastReport(Map<String, Object> createReportRequest) {
|
|
|
@@ -121,16 +235,131 @@ public class VppUnReportServiceImpl implements VppUnReportService {
|
|
|
log.info("已提交 RegulateForecastReportRequest");
|
|
|
}
|
|
|
|
|
|
+ private List<VppSite> listActiveSites(Integer tenantId) {
|
|
|
+ return siteMapper.selectList(new LambdaQueryWrapper<VppSite>()
|
|
|
+ .eq(VppSite::getDeleteFlag, VppAuditHelper.NOT_DELETED)
|
|
|
+ .eq(tenantId != null, VppSite::getTenantId, tenantId)
|
|
|
+ .orderByAsc(VppSite::getId));
|
|
|
+ }
|
|
|
+
|
|
|
private List<VppResourcePoint> listActiveResources(boolean controllableOnly) {
|
|
|
+ Integer tenantId = VppUnTenantContext.resolveTenantId();
|
|
|
LambdaQueryWrapper<VppResourcePoint> wrapper = new LambdaQueryWrapper<VppResourcePoint>()
|
|
|
.eq(VppResourcePoint::getDeleteFlag, VppAuditHelper.NOT_DELETED)
|
|
|
+ .eq(tenantId != null, VppResourcePoint::getTenantId, tenantId)
|
|
|
.orderByAsc(VppResourcePoint::getId);
|
|
|
if (controllableOnly) {
|
|
|
- wrapper.eq(VppResourcePoint::getIsControl, 1);
|
|
|
+ wrapper.eq(VppResourcePoint::getIsSupportPeak, 1);
|
|
|
}
|
|
|
return resourcePointMapper.selectList(wrapper);
|
|
|
}
|
|
|
|
|
|
+ private Map<Long, VppDevice> loadDeviceMap(List<VppResourcePoint> resources) {
|
|
|
+ if (resources == null || resources.isEmpty()) {
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+ List<Long> deviceIds = resources.stream()
|
|
|
+ .map(VppResourcePoint::getDeviceId)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (deviceIds.isEmpty()) {
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+ return deviceMapper.selectBatchIds(deviceIds).stream()
|
|
|
+ .filter(device -> device != null && !VppAuditHelper.isDeleted(device.getDeleteFlag()))
|
|
|
+ .collect(Collectors.toMap(VppDevice::getId, device -> device, (a, b) -> a));
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<Long, List<String>> groupPeakDeviceUuidsBySite(List<VppResourcePoint> peakResources,
|
|
|
+ Map<Long, VppDevice> deviceMap) {
|
|
|
+ Map<Long, List<String>> grouped = new HashMap<>();
|
|
|
+ if (peakResources == null || deviceMap == null) {
|
|
|
+ return grouped;
|
|
|
+ }
|
|
|
+ for (VppResourcePoint resource : peakResources) {
|
|
|
+ if (resource == null || resource.getSiteId() == null || resource.getDeviceId() == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ VppDevice device = deviceMap.get(resource.getDeviceId());
|
|
|
+ if (device == null || !StringUtils.hasText(device.getDeviceUuid())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ grouped.computeIfAbsent(resource.getSiteId(), key -> new ArrayList<>())
|
|
|
+ .add(device.getDeviceUuid().trim());
|
|
|
+ }
|
|
|
+ return grouped;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<String> collectDeviceUuids(List<VppResourcePoint> resources, Map<Long, VppDevice> deviceMap) {
|
|
|
+ if (resources == null || deviceMap == null) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ Set<String> uuids = new LinkedHashSet<>();
|
|
|
+ for (VppResourcePoint resource : resources) {
|
|
|
+ if (resource == null || resource.getDeviceId() == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ VppDevice device = deviceMap.get(resource.getDeviceId());
|
|
|
+ if (device != null && StringUtils.hasText(device.getDeviceUuid())) {
|
|
|
+ uuids.add(device.getDeviceUuid().trim());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return new ArrayList<>(uuids);
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<String> resolveMomentDataDeviceUuids(VppUnRegisterReportIndex.Entry entry,
|
|
|
+ List<String> tenantPeakDeviceUuids,
|
|
|
+ Map<Long, List<String>> peakDeviceUuidsBySite,
|
|
|
+ Map<Long, VppDevice> deviceMap) {
|
|
|
+ if (entry.getScope() == VppUnRegisterReportIndex.Scope.VPP) {
|
|
|
+ return tenantPeakDeviceUuids;
|
|
|
+ }
|
|
|
+ if (entry.getScope() == VppUnRegisterReportIndex.Scope.SITE && entry.getSite() != null) {
|
|
|
+ return peakDeviceUuidsBySite.getOrDefault(entry.getSite().getId(), Collections.emptyList());
|
|
|
+ }
|
|
|
+ if (entry.getScope() == VppUnRegisterReportIndex.Scope.RESOURCE && entry.getResource() != null) {
|
|
|
+ VppDevice device = deviceMap.get(entry.getResource().getDeviceId());
|
|
|
+ if (device != null && StringUtils.hasText(device.getDeviceUuid())) {
|
|
|
+ return Collections.singletonList(device.getDeviceUuid().trim());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<Long, String> loadDeviceUnResourceIdMap(List<VppResourcePoint> resources) {
|
|
|
+ if (resources == null || resources.isEmpty()) {
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+ List<Long> deviceIds = resources.stream()
|
|
|
+ .map(VppResourcePoint::getDeviceId)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (deviceIds.isEmpty()) {
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+ return deviceMapper.selectBatchIds(deviceIds).stream()
|
|
|
+ .filter(device -> device != null
|
|
|
+ && !VppAuditHelper.isDeleted(device.getDeleteFlag())
|
|
|
+ && StringUtils.hasText(device.getUnResourceId()))
|
|
|
+ .collect(Collectors.toMap(VppDevice::getId, VppDevice::getUnResourceId, (a, b) -> a));
|
|
|
+ }
|
|
|
+
|
|
|
+ private Set<LocalDate> loadResponseHistoryDates() {
|
|
|
+ List<VppDrEvent> events = drEventMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<VppDrEvent>()
|
|
|
+ .eq(VppDrEvent::getEventStatus, VppDrEventStatus.ENDED)
|
|
|
+ .eq(VppDrEvent::getDeleteFlag, VppAuditHelper.NOT_DELETED));
|
|
|
+ Set<LocalDate> dates = new LinkedHashSet<>();
|
|
|
+ for (VppDrEvent event : events) {
|
|
|
+ if (event.getStartTime() != null) {
|
|
|
+ dates.add(event.getStartTime().toLocalDate());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return dates;
|
|
|
+ }
|
|
|
+
|
|
|
@SuppressWarnings("unchecked")
|
|
|
private String resolveReportRequestId(Map<String, Object> request) {
|
|
|
String id = VppUnPayloadHelper.getString(request, "reportRequestID", "reportRequestId");
|