dev #3

Merged
dashixiong merged 11 commits from dev into waibao 2026-04-09 01:31:06 +00:00
123 changed files with 14485 additions and 3792 deletions
Showing only changes of commit 515f440298 - Show all commits

View File

@ -0,0 +1,61 @@
package com.xzzn.web.controller.ems;
import com.xzzn.common.annotation.Log;
import com.xzzn.common.core.controller.BaseController;
import com.xzzn.common.core.domain.AjaxResult;
import com.xzzn.common.core.page.TableDataInfo;
import com.xzzn.common.enums.BusinessType;
import com.xzzn.ems.domain.EmsDailyChargeData;
import com.xzzn.ems.service.IEmsDailyChargeDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 站点管理-充放电修正 Controller
*/
@RestController
@RequestMapping("/ems/dailyChargeData")
public class EmsDailyChargeDataController extends BaseController {
@Autowired
private IEmsDailyChargeDataService emsDailyChargeDataService;
@GetMapping("/list")
public TableDataInfo list(EmsDailyChargeData emsDailyChargeData) {
startPage();
List<EmsDailyChargeData> list = emsDailyChargeDataService.selectEmsDailyChargeDataList(emsDailyChargeData);
return getDataTable(list);
}
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) {
return success(emsDailyChargeDataService.selectEmsDailyChargeDataById(id));
}
@Log(title = "站点管理-充放电修正", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody EmsDailyChargeData emsDailyChargeData) {
return toAjax(emsDailyChargeDataService.insertEmsDailyChargeData(emsDailyChargeData, getUsername()));
}
@Log(title = "站点管理-充放电修正", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody EmsDailyChargeData emsDailyChargeData) {
return toAjax(emsDailyChargeDataService.updateEmsDailyChargeData(emsDailyChargeData, getUsername()));
}
@Log(title = "站点管理-充放电修正", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(emsDailyChargeDataService.deleteEmsDailyChargeDataByIds(ids));
}
}

View File

@ -0,0 +1,61 @@
package com.xzzn.web.controller.ems;
import com.xzzn.common.annotation.Log;
import com.xzzn.common.core.controller.BaseController;
import com.xzzn.common.core.domain.AjaxResult;
import com.xzzn.common.core.page.TableDataInfo;
import com.xzzn.common.enums.BusinessType;
import com.xzzn.ems.domain.EmsDailyEnergyData;
import com.xzzn.ems.service.IEmsDailyEnergyDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 站点管理-数据修正 Controller
*/
@RestController
@RequestMapping("/ems/dailyEnergyData")
public class EmsDailyEnergyDataController extends BaseController {
@Autowired
private IEmsDailyEnergyDataService emsDailyEnergyDataService;
@GetMapping("/list")
public TableDataInfo list(EmsDailyEnergyData emsDailyEnergyData) {
startPage();
List<EmsDailyEnergyData> list = emsDailyEnergyDataService.selectEmsDailyEnergyDataList(emsDailyEnergyData);
return getDataTable(list);
}
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) {
return success(emsDailyEnergyDataService.selectEmsDailyEnergyDataById(id));
}
@Log(title = "站点管理-数据修正", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody EmsDailyEnergyData emsDailyEnergyData) {
return toAjax(emsDailyEnergyDataService.insertEmsDailyEnergyData(emsDailyEnergyData, getUsername()));
}
@Log(title = "站点管理-数据修正", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody EmsDailyEnergyData emsDailyEnergyData) {
return toAjax(emsDailyEnergyDataService.updateEmsDailyEnergyData(emsDailyEnergyData, getUsername()));
}
@Log(title = "站点管理-数据修正", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(emsDailyEnergyDataService.deleteEmsDailyEnergyDataByIds(ids));
}
}

View File

@ -0,0 +1,35 @@
package com.xzzn.quartz.task;
import com.xzzn.common.utils.StringUtils;
import com.xzzn.ems.service.impl.DeviceDataProcessServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component("calcPointTask")
public class CalcPointTask {
private static final Logger log = LoggerFactory.getLogger(CalcPointTask.class);
@Autowired
private DeviceDataProcessServiceImpl deviceDataProcessService;
public void syncAllSites() {
log.info("开始执行计算点轮询任务-全站点");
deviceDataProcessService.syncCalcPointDataFromInfluxByQuartz();
log.info("结束执行计算点轮询任务-全站点");
}
public void syncBySite(String siteId) {
if (StringUtils.isBlank(siteId)) {
log.warn("计算点轮询任务参数为空,转为全站点执行");
syncAllSites();
return;
}
String normalizedSiteId = siteId.trim();
log.info("开始执行计算点轮询任务-单站点, siteId: {}", normalizedSiteId);
deviceDataProcessService.syncCalcPointDataFromInfluxByQuartz(normalizedSiteId);
log.info("结束执行计算点轮询任务-单站点, siteId: {}", normalizedSiteId);
}
}

View File

@ -0,0 +1,35 @@
package com.xzzn.quartz.task;
import com.xzzn.common.utils.StringUtils;
import com.xzzn.ems.service.impl.DeviceDataProcessServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component("dailyChargeDataTask")
public class DailyChargeDataTask {
private static final Logger log = LoggerFactory.getLogger(DailyChargeDataTask.class);
@Autowired
private DeviceDataProcessServiceImpl deviceDataProcessService;
public void syncAllSites() {
log.info("开始执行每日充放电数据轮询任务-全站点");
deviceDataProcessService.syncDailyChargeDataFromInfluxByQuartz();
log.info("结束执行每日充放电数据轮询任务-全站点");
}
public void syncBySite(String siteId) {
if (StringUtils.isBlank(siteId)) {
log.warn("每日充放电数据轮询任务参数为空,转为全站点执行");
syncAllSites();
return;
}
String normalizedSiteId = siteId.trim();
log.info("开始执行每日充放电数据轮询任务-单站点, siteId: {}", normalizedSiteId);
deviceDataProcessService.syncDailyChargeDataFromInfluxByQuartz(normalizedSiteId);
log.info("结束执行每日充放电数据轮询任务-单站点, siteId: {}", normalizedSiteId);
}
}

View File

@ -0,0 +1,38 @@
package com.xzzn.ems.domain.vo;
import javax.validation.constraints.NotBlank;
public class PointConfigGenerateRecentRequest {
@NotBlank(message = "站点ID不能为空")
private String siteId;
@NotBlank(message = "点位ID不能为空")
private String pointId;
private String deviceId;
public String getSiteId() {
return siteId;
}
public void setSiteId(String siteId) {
this.siteId = siteId;
}
public String getPointId() {
return pointId;
}
public void setPointId(String pointId) {
this.pointId = pointId;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
}

View File

@ -0,0 +1,21 @@
package com.xzzn.ems.service;
import com.xzzn.ems.domain.EmsDailyChargeData;
import java.util.List;
/**
* 站点每日充放电数据Service接口
*/
public interface IEmsDailyChargeDataService {
List<EmsDailyChargeData> selectEmsDailyChargeDataList(EmsDailyChargeData emsDailyChargeData);
EmsDailyChargeData selectEmsDailyChargeDataById(Long id);
int insertEmsDailyChargeData(EmsDailyChargeData emsDailyChargeData, String operName);
int updateEmsDailyChargeData(EmsDailyChargeData emsDailyChargeData, String operName);
int deleteEmsDailyChargeDataByIds(Long[] ids);
}

View File

@ -0,0 +1,21 @@
package com.xzzn.ems.service;
import com.xzzn.ems.domain.EmsDailyEnergyData;
import java.util.List;
/**
* 站点每日收益数据Service接口
*/
public interface IEmsDailyEnergyDataService {
List<EmsDailyEnergyData> selectEmsDailyEnergyDataList(EmsDailyEnergyData emsDailyEnergyData);
EmsDailyEnergyData selectEmsDailyEnergyDataById(Long id);
int insertEmsDailyEnergyData(EmsDailyEnergyData emsDailyEnergyData, String operName);
int updateEmsDailyEnergyData(EmsDailyEnergyData emsDailyEnergyData, String operName);
int deleteEmsDailyEnergyDataByIds(Long[] ids);
}

View File

@ -67,6 +67,7 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayDeque;
@ -131,6 +132,18 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
private static final String AUTO_HOUR_DIFF_CONTEXT_PREFIX = "__AUTO_HOUR_DIFF__";
private static final String MONITOR_FIELD_PREFIX_HOME = "home__";
private static final String MONITOR_FIELD_PREFIX_TJBB_DBBB = "tjbb_dbbb__";
private static final String FIELD_CODE_TOTAL_CHARGE = "home__totalChargedCap";
private static final String FIELD_CODE_TOTAL_DISCHARGE = "home__totalDischargedCap";
private static final String FIELD_CODE_DAY_CHARGE = "home__dayChargedCap";
private static final String FIELD_CODE_DAY_DISCHARGE = "home__dayDisChargedCap";
private static final String FIELD_CODE_PEAK_CHARGE = "tjbb_dbbb__activePeakKwh";
private static final String FIELD_CODE_PEAK_DISCHARGE = "tjbb_dbbb__reActivePeakKwh";
private static final String FIELD_CODE_HIGH_CHARGE = "tjbb_dbbb__activeHighKwh";
private static final String FIELD_CODE_HIGH_DISCHARGE = "tjbb_dbbb__reActiveHighKwh";
private static final String FIELD_CODE_FLAT_CHARGE = "tjbb_dbbb__activeFlatKwh";
private static final String FIELD_CODE_FLAT_DISCHARGE = "tjbb_dbbb__reActiveFlatKwh";
private static final String FIELD_CODE_VALLEY_CHARGE = "tjbb_dbbb__activeValleyKwh";
private static final String FIELD_CODE_VALLEY_DISCHARGE = "tjbb_dbbb__reActiveValleyKwh";
private static final String[] FIELD_SUFFIX_TOTAL_CHARGE = {
"activeTotalKwh", "totalChargeData", "totalCharge", "totalChargedCap", "chargedCap"
};
@ -401,8 +414,8 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
dayChargePointId,
dayDischargeMatch == null ? "null" : StringUtils.defaultString(dayDischargeMatch.getFieldCode()),
dayDischargePointId);
BigDecimal nowTotalCharge = getPointValueById(normalizedPointValueMap, totalChargePointId);
BigDecimal nowTotalDischarge = getPointValueById(normalizedPointValueMap, totalDischargePointId);
BigDecimal nowTotalCharge = getPointValueByIdRaw(normalizedPointValueMap, totalChargePointId);
BigDecimal nowTotalDischarge = getPointValueByIdRaw(normalizedPointValueMap, totalDischargePointId);
BigDecimal nowDayCharge = getLatestPointValueFromRedis(dayChargePointId);
BigDecimal nowDayDischarge = getLatestPointValueFromRedis(dayDischargePointId);
if (nowTotalCharge == null || nowTotalDischarge == null) {
@ -476,75 +489,109 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
Date queryEndTime = DateUtils.getNowDate();
Date queryStartTime = new Date(queryEndTime.getTime() - DAILY_CHARGE_INFLUX_QUERY_WINDOW_MS);
EmsSiteMonitorPointMatch totalChargeMatch = firstNonBlankMatchByFieldSuffixIgnoreDevice(
mappingList, FIELD_SUFFIX_TOTAL_CHARGE
);
EmsSiteMonitorPointMatch totalDischargeMatch = firstNonBlankMatchByFieldSuffixIgnoreDevice(
mappingList, FIELD_SUFFIX_TOTAL_DISCHARGE
);
String totalChargePointId = totalChargeMatch == null ? null : StringUtils.trimToNull(totalChargeMatch.getDataPoint());
String totalDischargePointId = totalDischargeMatch == null ? null : StringUtils.trimToNull(totalDischargeMatch.getDataPoint());
log.info("Quartz同步日充放电自检, siteId: {}, totalCharge: {}->{} , totalDischarge: {}->{}",
String totalChargePointId = resolvePointIdByFieldCodeIgnoreDevice(mappingList, FIELD_CODE_TOTAL_CHARGE);
String totalDischargePointId = resolvePointIdByFieldCodeIgnoreDevice(mappingList, FIELD_CODE_TOTAL_DISCHARGE);
String dayChargePointId = resolvePointIdByFieldCodeIgnoreDevice(mappingList, FIELD_CODE_DAY_CHARGE);
String dayDischargePointId = resolvePointIdByFieldCodeIgnoreDevice(mappingList, FIELD_CODE_DAY_DISCHARGE);
if (StringUtils.isBlank(dayChargePointId)) {
dayChargePointId = firstNonBlankPointByFieldSuffixIgnoreDevice(mappingList, FIELD_SUFFIX_DAY_CHARGE);
}
if (StringUtils.isBlank(dayDischargePointId)) {
dayDischargePointId = firstNonBlankPointByFieldSuffixIgnoreDevice(mappingList, FIELD_SUFFIX_DAY_DISCHARGE);
}
log.info("Quartz同步日充放电日累自检, siteId: {}, dayChargePoint: {}, dayDischargePoint: {}",
siteId,
dayChargePointId,
dayDischargePointId);
String peakChargePointId = resolvePointIdByFieldCodeIgnoreDevice(mappingList, FIELD_CODE_PEAK_CHARGE);
String peakDischargePointId = resolvePointIdByFieldCodeIgnoreDevice(mappingList, FIELD_CODE_PEAK_DISCHARGE);
String highChargePointId = resolvePointIdByFieldCodeIgnoreDevice(mappingList, FIELD_CODE_HIGH_CHARGE);
String highDischargePointId = resolvePointIdByFieldCodeIgnoreDevice(mappingList, FIELD_CODE_HIGH_DISCHARGE);
String flatChargePointId = resolvePointIdByFieldCodeIgnoreDevice(mappingList, FIELD_CODE_FLAT_CHARGE);
String flatDischargePointId = resolvePointIdByFieldCodeIgnoreDevice(mappingList, FIELD_CODE_FLAT_DISCHARGE);
String valleyChargePointId = resolvePointIdByFieldCodeIgnoreDevice(mappingList, FIELD_CODE_VALLEY_CHARGE);
String valleyDischargePointId = resolvePointIdByFieldCodeIgnoreDevice(mappingList, FIELD_CODE_VALLEY_DISCHARGE);
log.info("Quartz同步日充放电自检, siteId: {}, totalCharge: {} , totalDischarge: {}, dayCharge: {}, dayDischarge: {}, peak: {} / {}, high: {} / {}, flat: {} / {}, valley: {} / {}",
siteId,
totalChargeMatch == null ? "null" : StringUtils.defaultString(totalChargeMatch.getFieldCode()),
totalChargePointId,
totalDischargeMatch == null ? "null" : StringUtils.defaultString(totalDischargeMatch.getFieldCode()),
totalDischargePointId);
if (StringUtils.isBlank(totalChargePointId) && StringUtils.isBlank(totalDischargePointId)) {
log.info("Quartz同步日充放电跳过未找到总充/总放点位, siteId: {}", siteId);
return;
}
totalDischargePointId,
dayChargePointId,
dayDischargePointId,
peakChargePointId,
peakDischargePointId,
highChargePointId,
highDischargePointId,
flatChargePointId,
flatDischargePointId,
valleyChargePointId,
valleyDischargePointId);
Map<String, BigDecimal> pointIdValueMap = new HashMap<>();
Date dataUpdateTime = null;
if (StringUtils.isNotBlank(totalChargePointId)) {
InfluxPointDataWriter.PointValue totalChargePoint = influxPointDataWriter.queryLatestPointValueByPointKey(
siteId, totalChargePointId, queryStartTime, queryEndTime
);
if (totalChargePoint != null && totalChargePoint.getPointValue() != null) {
pointIdValueMap.put(totalChargePointId.trim().toUpperCase(), totalChargePoint.getPointValue());
dataUpdateTime = totalChargePoint.getDataTime();
} else {
log.info("Quartz同步日充放电未获取到总充点最新值, siteId: {}, pointId: {}, range: {} ~ {}",
siteId, totalChargePointId,
DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, queryStartTime),
DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, queryEndTime));
Map<String, LatestPointValue> latestPointValues = new HashMap<>();
Date latestDataTime = null;
for (String pointId : Arrays.asList(
totalChargePointId, totalDischargePointId,
dayChargePointId, dayDischargePointId,
peakChargePointId, peakDischargePointId,
highChargePointId, highDischargePointId,
flatChargePointId, flatDischargePointId,
valleyChargePointId, valleyDischargePointId)) {
if (StringUtils.isBlank(pointId)) {
continue;
}
LatestPointValue latestPointValue = getLatestPointValuePreferRedis(siteId, pointId, queryStartTime, queryEndTime);
if (latestPointValue == null || latestPointValue.getValue() == null) {
continue;
}
if (StringUtils.isNotBlank(totalDischargePointId)) {
InfluxPointDataWriter.PointValue totalDischargePoint = influxPointDataWriter.queryLatestPointValueByPointKey(
siteId, totalDischargePointId, queryStartTime, queryEndTime
);
if (totalDischargePoint != null && totalDischargePoint.getPointValue() != null) {
pointIdValueMap.put(totalDischargePointId.trim().toUpperCase(), totalDischargePoint.getPointValue());
if (dataUpdateTime == null
|| (totalDischargePoint.getDataTime() != null
&& totalDischargePoint.getDataTime().after(dataUpdateTime))) {
dataUpdateTime = totalDischargePoint.getDataTime();
}
} else {
log.info("Quartz同步日充放电未获取到总放点最新值, siteId: {}, pointId: {}, range: {} ~ {}",
siteId, totalDischargePointId,
DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, queryStartTime),
DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, queryEndTime));
latestPointValues.put(pointId.trim().toUpperCase(), latestPointValue);
if (latestPointValue.getDataTime() != null
&& (latestDataTime == null || latestPointValue.getDataTime().after(latestDataTime))) {
latestDataTime = latestPointValue.getDataTime();
}
}
if (org.apache.commons.collections4.MapUtils.isEmpty(pointIdValueMap)) {
if (latestPointValues.isEmpty()) {
log.info("Quartz同步日充放电跳过点位最新值为空, siteId: {}", siteId);
return;
}
if (dataUpdateTime == null) {
log.info("Quartz同步日充放电点位值存在但时间为空, siteId: {}, pointIds: {}",
siteId, pointIdValueMap.keySet());
Date recordDateTime = latestDataTime == null ? DateUtils.getNowDate() : latestDataTime;
BigDecimal totalChargeValue = getPointValueById(latestPointValues, totalChargePointId);
BigDecimal totalDischargeValue = getPointValueById(latestPointValues, totalDischargePointId);
BigDecimal dayChargeValue = getPointValueById(latestPointValues, dayChargePointId);
BigDecimal dayDischargeValue = getPointValueById(latestPointValues, dayDischargePointId);
log.info("单站点位值汇总, siteId: {}, totalCharge: {}({}), totalDischarge: {}({}), dayCharge: {}({}), dayDischarge: {}({}), dataTime: {}",
siteId,
totalChargeValue,
totalDischargeValue,
dayChargeValue,
dayDischargeValue,
pointValueSource(latestPointValues, totalChargePointId),
pointValueSource(latestPointValues, totalDischargePointId),
pointValueSource(latestPointValues, dayChargePointId),
pointValueSource(latestPointValues, dayDischargePointId),
DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, recordDateTime));
if (totalChargeValue == null && totalDischargeValue == null) {
log.info("Quartz同步日充放电跳过总充/总放值为空, siteId: {}", siteId);
} else {
log.info("Quartz同步日充放电准备落库, siteId: {}, dataUpdateTime: {}, pointIds: {}",
siteId, DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, dataUpdateTime),
pointIdValueMap.keySet());
upsertDailyChargeData(siteId, recordDateTime, totalChargeValue, totalDischargeValue, dayChargeValue, dayDischargeValue);
}
updateDailyChargeDataByQuartz(siteId, pointIdValueMap, dataUpdateTime);
updateDailyEnergyHourlyDataByQuartz(siteId, dataUpdateTime);
syncDailyChargeRevenueByQuartz(siteId, dataUpdateTime);
updateDailyEnergyHourlyDataByQuartz(
siteId,
recordDateTime,
peakChargePointId,
peakDischargePointId,
highChargePointId,
highDischargePointId,
flatChargePointId,
flatDischargePointId,
valleyChargePointId,
valleyDischargePointId,
queryStartTime,
queryEndTime
);
syncDailyChargeRevenueByQuartz(siteId, recordDateTime);
}
private void syncDailyChargeRevenueByQuartz(String siteId, Date dataUpdateTime) {
@ -576,7 +623,18 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
siteId, day, dayRevenue, totalRevenue);
}
private void updateDailyEnergyHourlyDataByQuartz(String siteId, Date dataUpdateTime) {
private void updateDailyEnergyHourlyDataByQuartz(String siteId,
Date dataUpdateTime,
String peakChargePointId,
String peakDischargePointId,
String highChargePointId,
String highDischargePointId,
String flatChargePointId,
String flatDischargePointId,
String valleyChargePointId,
String valleyDischargePointId,
Date queryStartTime,
Date queryEndTime) {
log.info("Quartz日电量小时落库入口, siteId: {}, dataTime: {}",
siteId,
dataUpdateTime == null ? "null" : DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, dataUpdateTime));
@ -584,15 +642,12 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
return;
}
List<EmsSiteMonitorPointMatch> mappingList = getPointMatchesBySiteId(siteId);
if (CollectionUtils.isEmpty(mappingList)) {
return;
}
Date recordDateTime = dataUpdateTime == null ? DateUtils.getNowDate() : dataUpdateTime;
Integer dataHour = resolveHourOfDay(recordDateTime);
String priceKey = RedisKeyConstants.ENERGY_PRICE_TIME + siteId + "_" + LocalDate.now().getYear() + LocalDate.now().getMonthValue();
LocalDateTime recordLocalTime = LocalDateTime.ofInstant(recordDateTime.toInstant(), ZoneId.systemDefault());
String priceKey = RedisKeyConstants.ENERGY_PRICE_TIME + siteId + "_" + recordLocalTime.getYear()
+ recordLocalTime.getMonthValue();
EnergyPriceVo priceVo = redisCache.getCacheObject(priceKey);
if (priceVo == null) {
priceVo = emsEnergyPriceConfigService.getCurrentMonthPrice(siteId);
@ -619,55 +674,15 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
return;
}
EmsSiteMonitorPointMatch peakChargeMatch = firstNonBlankMatchByFieldSuffixIgnoreDevice(
mappingList, FIELD_SUFFIX_PEAK_CHARGE, MONITOR_FIELD_PREFIX_TJBB_DBBB
);
EmsSiteMonitorPointMatch peakDischargeMatch = firstNonBlankMatchByFieldSuffixIgnoreDevice(
mappingList, FIELD_SUFFIX_PEAK_DISCHARGE, MONITOR_FIELD_PREFIX_TJBB_DBBB
);
EmsSiteMonitorPointMatch highChargeMatch = firstNonBlankMatchByFieldSuffixIgnoreDevice(
mappingList, FIELD_SUFFIX_HIGH_CHARGE, MONITOR_FIELD_PREFIX_TJBB_DBBB
);
EmsSiteMonitorPointMatch highDischargeMatch = firstNonBlankMatchByFieldSuffixIgnoreDevice(
mappingList, FIELD_SUFFIX_HIGH_DISCHARGE, MONITOR_FIELD_PREFIX_TJBB_DBBB
);
EmsSiteMonitorPointMatch flatChargeMatch = firstNonBlankMatchByFieldSuffixIgnoreDevice(
mappingList, FIELD_SUFFIX_FLAT_CHARGE, MONITOR_FIELD_PREFIX_TJBB_DBBB
);
EmsSiteMonitorPointMatch flatDischargeMatch = firstNonBlankMatchByFieldSuffixIgnoreDevice(
mappingList, FIELD_SUFFIX_FLAT_DISCHARGE, MONITOR_FIELD_PREFIX_TJBB_DBBB
);
EmsSiteMonitorPointMatch valleyChargeMatch = firstNonBlankMatchByFieldSuffixIgnoreDevice(
mappingList, FIELD_SUFFIX_VALLEY_CHARGE, MONITOR_FIELD_PREFIX_TJBB_DBBB
);
EmsSiteMonitorPointMatch valleyDischargeMatch = firstNonBlankMatchByFieldSuffixIgnoreDevice(
mappingList, FIELD_SUFFIX_VALLEY_DISCHARGE, MONITOR_FIELD_PREFIX_TJBB_DBBB
);
String peakChargePointId = peakChargeMatch == null ? null : StringUtils.trimToNull(peakChargeMatch.getDataPoint());
String peakDischargePointId = peakDischargeMatch == null ? null : StringUtils.trimToNull(peakDischargeMatch.getDataPoint());
String highChargePointId = highChargeMatch == null ? null : StringUtils.trimToNull(highChargeMatch.getDataPoint());
String highDischargePointId = highDischargeMatch == null ? null : StringUtils.trimToNull(highDischargeMatch.getDataPoint());
String flatChargePointId = flatChargeMatch == null ? null : StringUtils.trimToNull(flatChargeMatch.getDataPoint());
String flatDischargePointId = flatDischargeMatch == null ? null : StringUtils.trimToNull(flatDischargeMatch.getDataPoint());
String valleyChargePointId = valleyChargeMatch == null ? null : StringUtils.trimToNull(valleyChargeMatch.getDataPoint());
String valleyDischargePointId = valleyDischargeMatch == null ? null : StringUtils.trimToNull(valleyDischargeMatch.getDataPoint());
log.info("Quartz日电量小时自检, siteId: {}, peak: {}->{} / {}->{} , high: {}->{} / {}->{} , flat: {}->{} / {}->{} , valley: {}->{} / {}->{}",
log.info("Quartz日电量小时自检, siteId: {}, peak: {} / {} , high: {} / {} , flat: {} / {} , valley: {} / {}",
siteId,
peakChargeMatch == null ? "null" : StringUtils.defaultString(peakChargeMatch.getFieldCode()),
peakChargePointId,
peakDischargeMatch == null ? "null" : StringUtils.defaultString(peakDischargeMatch.getFieldCode()),
peakDischargePointId,
highChargeMatch == null ? "null" : StringUtils.defaultString(highChargeMatch.getFieldCode()),
highChargePointId,
highDischargeMatch == null ? "null" : StringUtils.defaultString(highDischargeMatch.getFieldCode()),
highDischargePointId,
flatChargeMatch == null ? "null" : StringUtils.defaultString(flatChargeMatch.getFieldCode()),
flatChargePointId,
flatDischargeMatch == null ? "null" : StringUtils.defaultString(flatDischargeMatch.getFieldCode()),
flatDischargePointId,
valleyChargeMatch == null ? "null" : StringUtils.defaultString(valleyChargeMatch.getFieldCode()),
valleyChargePointId,
valleyDischargeMatch == null ? "null" : StringUtils.defaultString(valleyDischargeMatch.getFieldCode()),
valleyDischargePointId);
String currentChargePointId;
String currentDischargePointId;
@ -677,26 +692,26 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
case "peak":
currentChargePointId = peakChargePointId;
currentDischargePointId = peakDischargePointId;
currentCharge = getLatestPointValueFromRedis(peakChargePointId);
currentDischarge = getLatestPointValueFromRedis(peakDischargePointId);
currentCharge = getLatestPointValuePreferRedisValue(siteId, peakChargePointId, queryStartTime, queryEndTime);
currentDischarge = getLatestPointValuePreferRedisValue(siteId, peakDischargePointId, queryStartTime, queryEndTime);
break;
case "high":
currentChargePointId = highChargePointId;
currentDischargePointId = highDischargePointId;
currentCharge = getLatestPointValueFromRedis(highChargePointId);
currentDischarge = getLatestPointValueFromRedis(highDischargePointId);
currentCharge = getLatestPointValuePreferRedisValue(siteId, highChargePointId, queryStartTime, queryEndTime);
currentDischarge = getLatestPointValuePreferRedisValue(siteId, highDischargePointId, queryStartTime, queryEndTime);
break;
case "flat":
currentChargePointId = flatChargePointId;
currentDischargePointId = flatDischargePointId;
currentCharge = getLatestPointValueFromRedis(flatChargePointId);
currentDischarge = getLatestPointValueFromRedis(flatDischargePointId);
currentCharge = getLatestPointValuePreferRedisValue(siteId, flatChargePointId, queryStartTime, queryEndTime);
currentDischarge = getLatestPointValuePreferRedisValue(siteId, flatDischargePointId, queryStartTime, queryEndTime);
break;
case "valley":
currentChargePointId = valleyChargePointId;
currentDischargePointId = valleyDischargePointId;
currentCharge = getLatestPointValueFromRedis(valleyChargePointId);
currentDischarge = getLatestPointValueFromRedis(valleyDischargePointId);
currentCharge = getLatestPointValuePreferRedisValue(siteId, valleyChargePointId, queryStartTime, queryEndTime);
currentDischarge = getLatestPointValuePreferRedisValue(siteId, valleyDischargePointId, queryStartTime, queryEndTime);
break;
default:
log.info("Quartz日电量小时落库跳过未知电价时段类型, siteId: {}, costType: {}", siteId, costType);
@ -751,9 +766,17 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
return false;
}
try {
String normalizedStartTime = startTime.trim();
String normalizedEndTime = endTime.trim();
LocalTime current = LocalTime.parse(DateUtils.parseDateToStr("HH:mm", dataUpdateTime));
LocalTime start = LocalTime.parse(startTime);
LocalTime end = LocalTime.parse(endTime);
LocalTime start = LocalTime.parse(normalizedStartTime);
// 兼容配置中的 24:00将其视为次日 00:00。
if ("24:00".equals(normalizedEndTime) || "24:00:00".equals(normalizedEndTime)) {
return !current.isBefore(start);
}
LocalTime end = LocalTime.parse(normalizedEndTime);
if (start.equals(end)) {
return true;
}
@ -997,18 +1020,38 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
return parsed == null ? new LinkedHashMap<>() : new LinkedHashMap<>(parsed);
}
private BigDecimal getPointValueById(Map<String, BigDecimal> pointIdValueMap, String pointId) {
private BigDecimal getPointValueById(Map<String, LatestPointValue> pointIdValueMap, String pointId) {
if (pointIdValueMap == null || pointIdValueMap.isEmpty() || StringUtils.isBlank(pointId)) {
return null;
}
LatestPointValue latestPointValue = pointIdValueMap.get(pointId.trim().toUpperCase());
return latestPointValue == null ? null : latestPointValue.getValue();
}
private BigDecimal getPointValueByIdRaw(Map<String, BigDecimal> pointIdValueMap, String pointId) {
if (pointIdValueMap == null || pointIdValueMap.isEmpty() || StringUtils.isBlank(pointId)) {
return null;
}
return pointIdValueMap.get(pointId.trim().toUpperCase());
}
private String pointValueSource(Map<String, LatestPointValue> pointIdValueMap, String pointId) {
if (pointIdValueMap == null || pointIdValueMap.isEmpty() || StringUtils.isBlank(pointId)) {
return "-";
}
LatestPointValue latestPointValue = pointIdValueMap.get(pointId.trim().toUpperCase());
if (latestPointValue == null) {
return "-";
}
return latestPointValue.isFromRedis() ? "Redis" : "Influx";
}
private BigDecimal getLatestPointValueFromRedis(String pointId) {
String normalizedPointId = StringUtils.trimToNull(pointId);
if (normalizedPointId == null) {
return null;
}
log.info("点位值自检-Redis读取, pointId: {}", normalizedPointId);
List<String> candidates = new ArrayList<>();
candidates.add(normalizedPointId);
String upperPointId = normalizedPointId.toUpperCase();
@ -1037,6 +1080,7 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
pointValue = readBigDecimalField(raw, "pointValue");
}
if (pointValue != null) {
log.info("点位值自检-Redis命中, pointId: {}, redisKey: {}", normalizedPointId, candidate);
return pointValue;
}
} catch (Exception ex) {
@ -1046,6 +1090,110 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
return null;
}
private LatestPointValue getLatestPointValuePreferRedis(String siteId, String pointId, Date queryStartTime, Date queryEndTime) {
if (StringUtils.isBlank(siteId) || StringUtils.isBlank(pointId)) {
return null;
}
BigDecimal redisValue = getLatestPointValueFromRedis(pointId);
if (redisValue != null) {
return new LatestPointValue(redisValue, null, true);
}
log.info("点位值自检-Influx读取, siteId: {}, pointId: {}, range: {} ~ {}",
siteId, pointId,
DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, queryStartTime),
DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, queryEndTime));
InfluxPointDataWriter.PointValue influxPointValue = influxPointDataWriter.queryLatestPointValueByPointKey(
siteId, pointId, queryStartTime, queryEndTime
);
if (influxPointValue == null || influxPointValue.getPointValue() == null) {
return null;
}
return new LatestPointValue(influxPointValue.getPointValue(), influxPointValue.getDataTime(), false);
}
private BigDecimal getLatestPointValuePreferRedisValue(String siteId, String pointId, Date queryStartTime, Date queryEndTime) {
LatestPointValue value = getLatestPointValuePreferRedis(siteId, pointId, queryStartTime, queryEndTime);
return value == null ? null : value.getValue();
}
private String resolvePointIdByFieldCodeIgnoreDevice(List<EmsSiteMonitorPointMatch> mappingList, String fieldCode) {
if (CollectionUtils.isEmpty(mappingList) || StringUtils.isBlank(fieldCode)) {
return null;
}
String normalized = fieldCode.trim().toLowerCase();
for (EmsSiteMonitorPointMatch mapping : mappingList) {
if (mapping == null || StringUtils.isBlank(mapping.getFieldCode())) {
continue;
}
String dataPoint = StringUtils.defaultString(mapping.getDataPoint()).trim();
if (StringUtils.isBlank(dataPoint) || DELETED_FIELD_MARK.equalsIgnoreCase(dataPoint)) {
continue;
}
if (mapping.getFieldCode().trim().toLowerCase().equals(normalized)) {
return dataPoint;
}
}
return null;
}
private void upsertDailyChargeData(String siteId,
Date recordDateTime,
BigDecimal totalChargeValue,
BigDecimal totalDischargeValue,
BigDecimal dayChargeValue,
BigDecimal dayDischargeValue) {
if (StringUtils.isBlank(siteId)) {
return;
}
Date persistTime = recordDateTime == null ? DateUtils.getNowDate() : recordDateTime;
EmsDailyChargeData dailyChargeData = new EmsDailyChargeData();
dailyChargeData.setSiteId(siteId);
dailyChargeData.setDateTime(persistTime);
dailyChargeData.setTotalChargeData(totalChargeValue);
dailyChargeData.setTotalDischargeData(totalDischargeValue);
dailyChargeData.setChargeData(dayChargeValue);
dailyChargeData.setDischargeData(dayDischargeValue);
EmsDailyChargeData existedDailyData = emsDailyChargeDataMapper.selectBySiteIdAndDateTime(siteId, persistTime);
if (existedDailyData != null && existedDailyData.getId() != null) {
dailyChargeData.setId(existedDailyData.getId());
dailyChargeData.setDateTime(existedDailyData.getDateTime());
}
Date now = DateUtils.getNowDate();
dailyChargeData.setCreateBy("system");
dailyChargeData.setCreateTime(now);
dailyChargeData.setUpdateBy("system");
dailyChargeData.setUpdateTime(now);
emsDailyChargeDataMapper.insertOrUpdateData(dailyChargeData);
log.info("日充放电累计落库完成, siteId: {}, totalCharge: {}, totalDischarge: {}, dayCharge: {}, dayDischarge: {}",
siteId, totalChargeValue, totalDischargeValue, dayChargeValue, dayDischargeValue);
}
private static class LatestPointValue {
private final BigDecimal value;
private final Date dataTime;
private final boolean fromRedis;
LatestPointValue(BigDecimal value, Date dataTime, boolean fromRedis) {
this.value = value;
this.dataTime = dataTime;
this.fromRedis = fromRedis;
}
public BigDecimal getValue() {
return value;
}
public Date getDataTime() {
return dataTime;
}
public boolean isFromRedis() {
return fromRedis;
}
}
private BigDecimal readBigDecimalField(Object source, String fieldName) {
Object fieldValue = readFieldValue(source, fieldName);
return StringUtils.getBigDecimal(fieldValue);
@ -1165,9 +1313,11 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
}
String normalizedSiteId = siteId.trim();
String redisKey = RedisKeyConstants.SITE_MONITOR_POINT_MATCH + normalizedSiteId;
log.info("单站映射自检-读取, siteId: {}, redisKey: {}", normalizedSiteId, redisKey);
Object cacheObj = redisCache.getCacheObject(redisKey);
List<EmsSiteMonitorPointMatch> cached = parsePointMatchCache(cacheObj);
if (cached != null) {
log.info("单站映射自检-命中缓存, siteId: {}, size: {}", normalizedSiteId, cached.size());
return cached;
}
List<EmsSiteMonitorPointMatch> latest = emsSiteMonitorPointMatchMapper.selectBySiteId(normalizedSiteId);
@ -1175,6 +1325,7 @@ public class DeviceDataProcessServiceImpl extends AbstractBatteryDataProcessor i
latest = Collections.emptyList();
}
redisCache.setCacheObject(redisKey, latest, MONITOR_POINT_MATCH_REDIS_TTL_SECONDS, TimeUnit.SECONDS);
log.info("单站映射自检-落库后写缓存, siteId: {}, size: {}", normalizedSiteId, latest.size());
return latest;
}

View File

@ -0,0 +1,49 @@
package com.xzzn.ems.service.impl;
import com.xzzn.common.utils.DateUtils;
import com.xzzn.ems.domain.EmsDailyChargeData;
import com.xzzn.ems.mapper.EmsDailyChargeDataMapper;
import com.xzzn.ems.service.IEmsDailyChargeDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 站点每日充放电数据Service实现
*/
@Service
public class EmsDailyChargeDataServiceImpl implements IEmsDailyChargeDataService {
@Autowired
private EmsDailyChargeDataMapper emsDailyChargeDataMapper;
@Override
public List<EmsDailyChargeData> selectEmsDailyChargeDataList(EmsDailyChargeData emsDailyChargeData) {
return emsDailyChargeDataMapper.selectEmsDailyChargeDataList(emsDailyChargeData);
}
@Override
public EmsDailyChargeData selectEmsDailyChargeDataById(Long id) {
return emsDailyChargeDataMapper.selectEmsDailyChargeDataById(id);
}
@Override
public int insertEmsDailyChargeData(EmsDailyChargeData emsDailyChargeData, String operName) {
emsDailyChargeData.setCreateBy(operName);
emsDailyChargeData.setCreateTime(DateUtils.getNowDate());
return emsDailyChargeDataMapper.insertEmsDailyChargeData(emsDailyChargeData);
}
@Override
public int updateEmsDailyChargeData(EmsDailyChargeData emsDailyChargeData, String operName) {
emsDailyChargeData.setUpdateBy(operName);
emsDailyChargeData.setUpdateTime(DateUtils.getNowDate());
return emsDailyChargeDataMapper.updateEmsDailyChargeData(emsDailyChargeData);
}
@Override
public int deleteEmsDailyChargeDataByIds(Long[] ids) {
return emsDailyChargeDataMapper.deleteEmsDailyChargeDataByIds(ids);
}
}

View File

@ -0,0 +1,49 @@
package com.xzzn.ems.service.impl;
import com.xzzn.common.utils.DateUtils;
import com.xzzn.ems.domain.EmsDailyEnergyData;
import com.xzzn.ems.mapper.EmsDailyEnergyDataMapper;
import com.xzzn.ems.service.IEmsDailyEnergyDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 站点每日收益数据Service实现
*/
@Service
public class EmsDailyEnergyDataServiceImpl implements IEmsDailyEnergyDataService {
@Autowired
private EmsDailyEnergyDataMapper emsDailyEnergyDataMapper;
@Override
public List<EmsDailyEnergyData> selectEmsDailyEnergyDataList(EmsDailyEnergyData emsDailyEnergyData) {
return emsDailyEnergyDataMapper.selectEmsDailyEnergyDataList(emsDailyEnergyData);
}
@Override
public EmsDailyEnergyData selectEmsDailyEnergyDataById(Long id) {
return emsDailyEnergyDataMapper.selectEmsDailyEnergyDataById(id);
}
@Override
public int insertEmsDailyEnergyData(EmsDailyEnergyData emsDailyEnergyData, String operName) {
emsDailyEnergyData.setCreateBy(operName);
emsDailyEnergyData.setCreateTime(DateUtils.getNowDate());
return emsDailyEnergyDataMapper.insertEmsDailyEnergyData(emsDailyEnergyData);
}
@Override
public int updateEmsDailyEnergyData(EmsDailyEnergyData emsDailyEnergyData, String operName) {
emsDailyEnergyData.setUpdateBy(operName);
emsDailyEnergyData.setUpdateTime(DateUtils.getNowDate());
return emsDailyEnergyDataMapper.updateEmsDailyEnergyData(emsDailyEnergyData);
}
@Override
public int deleteEmsDailyEnergyDataByIds(Long[] ids) {
return emsDailyEnergyDataMapper.deleteEmsDailyEnergyDataByIds(ids);
}
}