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> 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> hourList = new ArrayList<>(); List> dayList = new ArrayList<>(); List> monthList = new ArrayList<>(); List> yearList = new ArrayList<>(); for (Map floorInfo : floorInfos) { String buildingId = floorInfo.get("id").toString(); String buildingName = floorInfo.get("building_name").toString(); // 根据楼栋id查询对应楼层下的所有设备 //TODO 2、计算每小时用电量、用水量、单耗(用电量/用水量) Map hourMap = processEnergy(buildingId, buildingName, lastHourTime, tableName, "hour", EnergyType.HOUR); if (null != hourMap) { hourList.add(hourMap); } //TODO 3、计算每日用用电量、用水量、单耗(用电量/用水量) Map dayMap = processEnergy(buildingId, buildingName, lastHourTime, tableName, "day", EnergyType.DAY); if (null != dayMap) { dayList.add(dayMap); } //TODO 4、计算月用电量、用水量、单耗(用电量/用水量) Map monthMap = processEnergy(buildingId, buildingName, lastHourTime, tableName, "month", EnergyType.MONTH); if (null != monthMap) { monthList.add(monthMap); } //TODO 5、计算年用电量、用水量、单耗(用电量/用水量) Map 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> dataList, String lastHourTime) { if (dataList.isEmpty()) return; double electricity = 0.0; double water = 0.0; for (Map 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 processEnergy(String buildingId, String buildingName, String curDate, String tableName, String dateType, EnergyType energyType) { List datas = energyQueryService.queryEnergyDatas(tableName, buildingId, curDate, dateType); Map 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> 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; } }