高效能源监控管理系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

291 lines
10 KiB

package com.mh.quartz.task;
import com.mh.common.constant.EnergyType;
import com.mh.common.core.domain.entity.DataMonth;
import com.mh.common.utils.StringUtils;
import com.mh.system.service.device.IDeviceLedgerService;
import com.mh.system.service.energy.IEnergyQueryService;
import com.mh.system.service.energy.IWaterLevelService;
import com.mh.system.service.energy.IWaterTempService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author LJF
* @version 1.0
* @project EEMCS
* @description 生活热水供水系统定时器
* @date 2025-06-17 16:12:04
*/
@Slf4j
@Component("hotWaterTask")
public class HotWaterTask {
@Resource
private IDeviceLedgerService deviceLedgerService;
@Resource
private IEnergyQueryService energyQueryService;
@Resource
private IWaterTempService waterTempService;
@Resource
private IWaterLevelService waterLevelService;
private boolean createOrUpdateDeviceState = false;
// 计算能耗表
private boolean calcEnergyState = false;
// 计算楼层能耗数据
private boolean calcFloorEnergyState = false;
// 计算热水温度状态
private boolean calcWaterTempState = false;
// 计算水箱水位
private boolean calcWaterLevelState = false;
// 计算数据分析
private boolean calcAnalysisState = false;
/**
* 定时数据分析
* @param lastHourTime
*/
public void calcAnalysisData(String lastHourTime) {
try {
if (!calcAnalysisState) {
calcAnalysisState = true;
if (StringUtils.isEmpty(lastHourTime)) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime lastHour = now.minusHours(1);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
lastHourTime = lastHour.format(formatter);
}
energyQueryService.calcAnalysisData(lastHourTime);
}
} catch (Exception e) {
log.error("计算数据分析", e);
calcAnalysisState = false;
} finally {
calcAnalysisState = false;
}
}
/**
* 定时计算水箱水位,插入到存储表中
*/
public void calcWaterLevel() {
try {
if (!calcWaterLevelState) {
calcWaterLevelState = true;
waterLevelService.calcWaterLevel();
}
} catch (Exception e) {
log.error("计算水箱水位失败", e);
calcWaterLevelState = false;
} finally {
calcWaterLevelState = false;
}
}
/**
* 新增或者更新设备状态表
*/
public void createOrUpdateDeviceState() {
try {
if (!createOrUpdateDeviceState) {
createOrUpdateDeviceState = true;
deviceLedgerService.createOrUpdateDeviceState();
}
} catch (Exception e) {
log.error("新增或者更新设备状态表失败", e);
createOrUpdateDeviceState = false;
} finally {
createOrUpdateDeviceState = false;
}
}
/**
* 定时计算水温度,插入到存储表中
*/
public void calcWaterTemp() {
try {
if (!calcWaterTempState) {
calcWaterTempState = true;
waterTempService.calcWaterTemp();
}
} catch (Exception e) {
log.error("计算水温度失败", e);
calcWaterTempState = false;
} finally {
calcWaterTempState = false;
}
}
/**
* 定时计算楼层能耗数据
* @param lastHourTime
*/
public void calcFloorEnergyData(String lastHourTime) {
try {
if (!calcFloorEnergyState) {
calcFloorEnergyState = true;
if (StringUtils.isEmpty(lastHourTime)) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime lastHour = now.minusHours(1);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
lastHourTime = lastHour.format(formatter);
}
energyQueryService.calcFloorEnergyDataDetail(lastHourTime);
}
} catch (Exception e) {
log.error("计算楼层能耗数据失败", e);
calcFloorEnergyState = false;
} finally {
calcFloorEnergyState = false;
}
}
/**
* 定时计算能耗数据任务
* @param lastHourTime
*/
public void calcEnergyData(String lastHourTime) {
try {
if (!calcEnergyState) {
calcEnergyState = true;
calcEnergyDataDetail(lastHourTime);
}
} catch (Exception e) {
log.error("计算能耗表失败", e);
calcEnergyState = false;
} finally {
calcEnergyState = false;
}
}
/**
* 计算能耗表
*/
public void calcEnergyDataDetail(String lastHourTime) {
//TODO 1、查询sql获取对应计算的楼层id、楼层名称用来当作楼栋id和楼栋名称
List<Map<String, Object>> floorInfos = energyQueryService.queryFloorInfo();
// 开始遍历
if (StringUtils.isEmpty(lastHourTime)) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime lastHour = now.minusHours(1);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
lastHourTime = lastHour.format(formatter);
}
String tableName = "data_hour" + lastHourTime.substring(0, 4);
List<Map<String, Double>> hourList = new ArrayList<>();
List<Map<String, Double>> dayList = new ArrayList<>();
List<Map<String, Double>> monthList = new ArrayList<>();
List<Map<String, Double>> yearList = new ArrayList<>();
for (Map<String, Object> floorInfo : floorInfos) {
String buildingId = floorInfo.get("id").toString();
String buildingName = floorInfo.get("building_name").toString();
// 根据楼栋id查询对应楼层下的所有设备
//TODO 2、计算每小时用电量、用水量、单耗(用电量/用水量)
Map<String, Double> hourMap = processEnergy(buildingId, buildingName, lastHourTime, tableName, "hour", EnergyType.HOUR);
if (null != hourMap) {
hourList.add(hourMap);
}
//TODO 3、计算每日用用电量、用水量、单耗(用电量/用水量)
Map<String, Double> dayMap = processEnergy(buildingId, buildingName, lastHourTime, tableName, "day", EnergyType.DAY);
if (null != dayMap) {
dayList.add(dayMap);
}
//TODO 4、计算月用电量、用水量、单耗(用电量/用水量)
Map<String, Double> monthMap = processEnergy(buildingId, buildingName, lastHourTime, tableName, "month", EnergyType.MONTH);
if (null != monthMap) {
monthList.add(monthMap);
}
//TODO 5、计算年用电量、用水量、单耗(用电量/用水量)
Map<String, Double> yearMap = processEnergy(buildingId, buildingName, lastHourTime, tableName, "year", EnergyType.YEAR);
if (null != yearMap) {
yearList.add(yearMap);
}
}
// 更新插入所有楼栋的数据表
processAndInsertEnergyData("hour", hourList, lastHourTime);
processAndInsertEnergyData("day", dayList, lastHourTime);
processAndInsertEnergyData("month", monthList, lastHourTime);
processAndInsertEnergyData("year", yearList, lastHourTime);
}
private void processAndInsertEnergyData(String timeUnit, List<Map<String, Double>> dataList, String lastHourTime) {
if (dataList.isEmpty()) return;
double electricity = 0.0;
double water = 0.0;
for (Map<String, Double> map : dataList) {
electricity += map.getOrDefault("electricity", 0.0);
water += map.getOrDefault("water", 0.0);
}
double specificConsumption = water > 0 ? electricity / water : 0.0;
energyQueryService.insertOrUpdateEnergyData(timeUnit, "所有", "所有", lastHourTime, electricity, water, specificConsumption);
}
private Map<String, Double> processEnergy(String buildingId, String buildingName, String curDate, String tableName, String dateType, EnergyType energyType) {
List<DataMonth> datas = energyQueryService.queryEnergyDatas(tableName, buildingId, curDate, dateType);
Map<String, Double> result = new HashMap<>();
double electricity = 0.0;
double water = 0.0;
double specificConsumption = 0.0;
if (datas == null || datas.isEmpty()) {
log.warn("未找到 {} 类型的能耗数据,buildingId={}, curDate={}", energyType, buildingId, curDate);
result.put("electricity", electricity);
result.put("water", water);
} else {
Map<String, List<DataMonth>> grouped = datas.stream()
.collect(Collectors.groupingBy(DataMonth::getDeviceType));
electricity = grouped.getOrDefault("5", Collections.emptyList()).stream()
.mapToDouble(data -> Optional.ofNullable(data.getCalcValue()).map(BigDecimal::doubleValue).orElse(0.0))
.sum();
result.put("electricity", electricity);
water = grouped.getOrDefault("23", Collections.emptyList()).stream()
.mapToDouble(data -> Optional.ofNullable(data.getCalcValue()).map(BigDecimal::doubleValue).orElse(0.0))
.sum();
result.put("water", water);
specificConsumption = water > 0 ? electricity / water : 0.0;
log.info("楼栋: {}, {}电表总量: {}, 水表总量: {}, 单耗: {}", buildingName, energyType, electricity, water, specificConsumption);
}
energyQueryService.insertOrUpdateEnergyData(
energyType.getCode(), buildingId, buildingName, curDate,
electricity,
water,
specificConsumption
);
return result;
}
}