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
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; |
|
} |
|
|
|
}
|
|
|