package com.iailab.module.ansteel.api.controller.admin; import cn.hutool.core.util.NumberUtil; import com.alibaba.fastjson.JSONObject; import com.iailab.framework.common.exception.enums.GlobalErrorCodeConstants; import com.iailab.framework.common.pojo.CommonResult; import com.iailab.framework.common.util.date.DateUtils; import com.iailab.framework.common.util.object.ConvertUtils; import com.iailab.module.ansteel.api.dto.*; import com.iailab.module.ansteel.power.entity.*; import com.iailab.module.ansteel.power.service.*; import com.iailab.module.data.api.point.DataPointApi; import com.iailab.module.data.api.point.dto.ApiPointValueDTO; import com.iailab.module.data.api.point.dto.ApiPointValueQueryDTO; import com.iailab.module.data.api.point.dto.ApiPointsValueQueryDTO; import com.iailab.module.model.api.mcs.McsApi; import com.iailab.module.model.api.mcs.dto.PredictLastValueReqVO; import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; import static com.iailab.framework.common.pojo.CommonResult.success; /** * 电力接口 * * @author PanZhibao * @Description * @createTime 2025年04月11日 */ @Slf4j @RestController @RequestMapping("/ansteel/api/power") public class PowerController { @Autowired private PowerNetFactorService powerNetFactorService; @Autowired private PowerCapacitorStatusService powerCapacitorStatusService; @Autowired private PowerControlMainService powerControlMainService; @Autowired private PowerControlDetService powerControlDetService; @Autowired private PowerGenStatusDaoService powerGenStatusDaoService; @Autowired private PowerDemandService powerDemandService; @Autowired private PowerAdjustedFactorService powerAdjustedFactorService; @Resource private DataPointApi dataPointApi; @Resource private McsApi mcsApi; @GetMapping("/net-factor/list") @Operation(summary = "功率因数-电网拓扑") public CommonResult> getPowerNetFactorList(@RequestParam Map params) { List list = powerNetFactorService.list(params); List result = ConvertUtils.sourceToTarget(list, PowerNetFactorDTO.class); if (CollectionUtils.isEmpty(result)) { return success(result); } Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.MILLISECOND, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.HOUR_OF_DAY, 0); for (PowerNetFactorDTO dto : result) { boolean cosFlag = false; try { List points = new ArrayList<>(); if (StringUtils.isNotBlank(dto.getCurP())) { points.add(dto.getCurP()); } if (StringUtils.isNotBlank(dto.getCurQ())) { points.add(dto.getCurQ()); } if (!CollectionUtils.isEmpty(points)) { Map pointsRealValue = dataPointApi.queryPointsRealValue(points); if (pointsRealValue.get(dto.getCurP()) != null) { dto.setCurP(pointsRealValue.get(dto.getCurP()).toString()); } if (pointsRealValue.get(dto.getCurQ()) != null) { dto.setCurQ(pointsRealValue.get(dto.getCurQ()).toString()); } if (pointsRealValue.get(dto.getCurCos()) != null) { dto.setCurCos(pointsRealValue.get(dto.getCurCos()).toString()); cosFlag = true; } } } catch (Exception ex) { log.info(dto.getNodeName() + "获取当前值异常" + ex.getMessage()); } try { PredictLastValueReqVO reqVO = new PredictLastValueReqVO(); reqVO.setPredictTime(calendar.getTime()); List itemNos = new ArrayList<>(); if (StringUtils.isNotBlank(dto.getPreP())) { itemNos.add(dto.getPreP().split(",")); } if (StringUtils.isNotBlank(dto.getPreQ())) { itemNos.add(dto.getPreQ().split(",")); } if (StringUtils.isNotBlank(dto.getPreCos())) { itemNos.add(dto.getPreCos().split(",")); } if (!CollectionUtils.isEmpty(itemNos)) { reqVO.setItemNos(itemNos); log.info("reqVO=" + JSONObject.toJSONString(reqVO)); Map preValues = mcsApi.getPredictValueByTime(reqVO); if (StringUtils.isNotBlank(dto.getPreP()) && preValues.get(dto.getPreP()) != null) { dto.setPreP(preValues.get(dto.getPreP()).toString()); } if (StringUtils.isNotBlank(dto.getPreQ()) && preValues.get(dto.getPreQ()) != null) { dto.setPreQ(preValues.get(dto.getPreQ()).toString()); } if (StringUtils.isNotBlank(dto.getPreCos()) && preValues.get(dto.getPreCos()) != null) { dto.setPreCos(preValues.get(dto.getPreCos()).toString()); } } } catch (Exception ex) { log.info(dto.getNodeName() + "获取预测值异常," + ex.getMessage()); } // 设置状态 if (cosFlag && StringUtils.isNotBlank(dto.getCurCos()) && NumberUtil.isNumber(dto.getCurCos())) { BigDecimal curCos = new BigDecimal(dto.getCurCos()); if (dto.getLimitL() != null && dto.getLimitH() != null && curCos.compareTo(dto.getLimitL()) < 0 || curCos.compareTo(dto.getLimitH()) > 0) { dto.setStatus(1); } else { dto.setStatus(0); } } } return success(result); } @GetMapping("/net-factor-dropdown/list") @Operation(summary = "功率因数-电网拓扑下拉列表") public CommonResult> getPowerNetFactorDropdownList(@RequestParam String nodeCode) { log.info("nodeCode=" + nodeCode); List list = powerNetFactorService.listDropdown(nodeCode); return success(ConvertUtils.sourceToTarget(list, PowerNetFactorDropdownDTO.class)); } /** * 判断 curCos 是否超上下限 * {nodeName}功率因数超上限/下限。 *

* 判断 curQ * {nodeName}发生无功返送 */ @GetMapping("/net-factor/alarm") @Operation(summary = "功率因数-电网拓扑预警信息") public CommonResult> getPowerNetFactorAlarm(@RequestParam Map params) { List result = new ArrayList<>(); List list = powerNetFactorService.list(params); List dtoList = ConvertUtils.sourceToTarget(list, PowerNetFactorDTO.class); if (CollectionUtils.isEmpty(dtoList)) { return success(result); } for (PowerNetFactorDTO dto : dtoList) { List points = new ArrayList<>(); String message = ""; if (StringUtils.isNotBlank(dto.getCurQ())) { points.add(dto.getCurQ()); } if (StringUtils.isNotBlank(dto.getCurCos())) { points.add(dto.getCurCos()); } if (CollectionUtils.isEmpty(points)) { continue; } Map pointsRealValue = dataPointApi.queryPointsRealValue(points); if (pointsRealValue.get(dto.getCurQ()) != null) { BigDecimal curQ = new BigDecimal(pointsRealValue.get(dto.getCurQ()).toString()); if (curQ.compareTo(BigDecimal.ZERO) == dto.getCurFlag()) { message = dto.getNodeName() + "发生无功返送;"; } } if (pointsRealValue.get(dto.getCurCos()) != null) { BigDecimal curCos = new BigDecimal(pointsRealValue.get(dto.getCurCos()).toString()); if (curCos.compareTo(dto.getLimitH()) > 0) { message += dto.getNodeName() + "功率因数超上限"; } else if (curCos.compareTo(dto.getLimitL()) < 0) { message += dto.getNodeName() + "功率因数超下限"; } } if (!message.isEmpty()) { result.add(message); } } return success(result); } @GetMapping("/gen-status/list") @Operation(summary = "功率因数-发电机组实时状态") public CommonResult> getPowerGenStatusList(@RequestParam Map params) { List list = powerGenStatusDaoService.list(params); List result = ConvertUtils.sourceToTarget(list, PowerGenStatusDTO.class); if (CollectionUtils.isEmpty(result)) { return success(result); } for (PowerGenStatusDTO dto : result) { List points = new ArrayList<>(); if (StringUtils.isNotBlank(dto.getCurP())) { points.add(dto.getCurP()); } if (StringUtils.isNotBlank(dto.getCurQ())) { points.add(dto.getCurQ()); } if (!CollectionUtils.isEmpty(points)) { Map pointsRealValue = dataPointApi.queryPointsRealValue(points); if (pointsRealValue.get(dto.getCurP()) != null) { dto.setCurP(pointsRealValue.get(dto.getCurP()).toString()); } if (pointsRealValue.get(dto.getCurQ()) != null) { dto.setCurQ(pointsRealValue.get(dto.getCurQ()).toString()); } } } return success(result); } @GetMapping("/capacitor-status/list") @Operation(summary = "功率因数-电容器投运状态") public CommonResult> getPowerCapacitorStatusList(@RequestParam Map params) { List list = powerCapacitorStatusService.list(params); return success(ConvertUtils.sourceToTarget(list, PowerCapacitorStatusDTO.class)); } @GetMapping("/control-main/list") @Operation(summary = "功率因数-管控变电站列表") public CommonResult> getPowerControlMainList(@RequestParam Map params) { List list = powerControlMainService.list(params); return success(ConvertUtils.sourceToTarget(list, PowerControlMainDTO.class)); } @PostMapping("/control-main/update") @Operation(summary = "功率因数-管控变电站修改上下限") public CommonResult updatePowerControlMain(@RequestBody PowerControlMainDTO dto) { if (StringUtils.isBlank(dto.getId())) { return CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST); } PowerControlMainEntity entity = new PowerControlMainEntity(); entity.setId(dto.getId()); entity.setLimitH(dto.getLimitH()); entity.setLimitL(dto.getLimitL()); powerControlMainService.update(entity); return success(true); } @GetMapping("/control-det/list") @Operation(summary = "功率因数-管控功率因数详情") public CommonResult> getPowerControlDetList(@RequestParam Map params) { List result = new ArrayList<>(); String name = (String) params.get("name"); if (StringUtils.isBlank(name)) { return CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST); } PowerControlMainEntity main = powerControlMainService.getByName(name); if (main == null) { return CommonResult.error(GlobalErrorCodeConstants.NOT_FOUND); } List list = powerControlDetService.list(main.getId()); result = ConvertUtils.sourceToTarget(list, PowerControlDetDTO.class); result.forEach(item -> { // 设置随机数据,0.8左右 Random rand = new Random(); int min = 700; int max = 900; int randomNumber = rand.nextInt(max - min + 1) + min; BigDecimal rv = new BigDecimal(randomNumber * 0.001).setScale(4, BigDecimal.ROUND_HALF_UP); item.setValue(rv); if (item.getLimitL() != null && rv.compareTo(item.getLimitL()) < 0) { item.setStatus(1); } else { item.setStatus(0); } }); return success(result); } @GetMapping("/demand/list") @Operation(summary = "负荷移植-月最大需量,实测需量,有功功率") public CommonResult> getPowerDemandList(@RequestParam Map params) { List list = powerDemandService.list(params); List result = ConvertUtils.sourceToTarget(list, PowerDemandDTO.class); if (CollectionUtils.isEmpty(result)) { return success(result); } for (PowerDemandDTO dto : result) { List points = new ArrayList<>(); if (StringUtils.isNotBlank(dto.getCurDemand())) { points.add(dto.getCurDemand()); } if (StringUtils.isNotBlank(dto.getActivePower())) { points.add(dto.getActivePower()); } if (!CollectionUtils.isEmpty(points)) { Map pointsRealValue = dataPointApi.queryPointsRealValue(points); if (pointsRealValue.get(dto.getCurDemand()) != null) { dto.setCurDemand(pointsRealValue.get(dto.getCurDemand()).toString()); } if (pointsRealValue.get(dto.getActivePower()) != null) { dto.setActivePower(pointsRealValue.get(dto.getActivePower()).toString()); } } if (!StringUtils.isEmpty(dto.getMaxDemand())) { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.DAY_OF_MONTH, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); Date start = calendar.getTime(); ApiPointValueQueryDTO apiPointValueQueryDTO = new ApiPointValueQueryDTO(); apiPointValueQueryDTO.setStart(start); apiPointValueQueryDTO.setEnd(new Date()); apiPointValueQueryDTO.setPointNo(dto.getMaxDemand()); List monthValues = dataPointApi.queryPointHistoryValue(apiPointValueQueryDTO); double max = 0; for (int i = 0; i < monthValues.size() - 1; i++) { if (max < monthValues.get(i).getV()) { max = monthValues.get(i).getV(); } } dto.setMaxDemand(String.valueOf(max)); } } return success(result); } @PostMapping("/net-factor/history") @Operation(summary = "功率因数-根据nodeName获取最近1440min历史数据,月最大,最小值") public CommonResult getPowerHistoryData(@RequestBody PowerNetFactorHisReqDTO dto) { log.info("PowerNetFactorHisReqDTO=" + JSONObject.toJSONString(dto)); String nodeCode = dto.getNodeCode(); if (StringUtils.isBlank(nodeCode)) { return CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST); } String queryType = dto.getQueryType(); if (StringUtils.isBlank(queryType)) { return CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST); } PowerNetFactorEntity powerNetFactor = powerNetFactorService.getByNodeCode(nodeCode); PowerHistoryDTO result = new PowerHistoryDTO(); if (powerNetFactor == null) { log.info("powerNetFactor is null"); return success(result); } log.info("开始查询,"); ApiPointValueQueryDTO apiPointValueQueryDTO = new ApiPointValueQueryDTO(); String pointNo = ""; switch (queryType.toUpperCase()) { case "P": pointNo = powerNetFactor.getCurP(); break; case "Q": pointNo = powerNetFactor.getCurQ(); break; case "COS": pointNo = powerNetFactor.getCurCos(); break; default: break; } //查询图表 apiPointValueQueryDTO.setPointNo(pointNo); Calendar calendar0 = Calendar.getInstance(); calendar0.set(Calendar.MILLISECOND, 0); calendar0.set(Calendar.SECOND, 0); Date end = dto.getEndTime() == null ? calendar0.getTime() : dto.getEndTime(); calendar0.add(Calendar.MINUTE, -1440); Date start = dto.getStartTime() == null ? calendar0.getTime() : dto.getStartTime(); apiPointValueQueryDTO.setEnd(end); apiPointValueQueryDTO.setStart(start); List chartData = dataPointApi.queryPointHistoryValue(apiPointValueQueryDTO); List dataList = new ArrayList<>(); for (ApiPointValueDTO pv : chartData) { Object[] data = new Object[2]; data[0] = DateUtils.format(pv.getT(), DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND); data[1] = pv.getV(); dataList.add(data); } List categories = DateUtils.getTimeScale(start, end, 60); result.setCategories(categories); result.setDataList(dataList); //查询月最大最小值 Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.DAY_OF_MONTH, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); start = calendar.getTime(); apiPointValueQueryDTO.setStart(start); apiPointValueQueryDTO.setEnd(new Date()); List monthChartData = dataPointApi.queryPointHistoryValue(apiPointValueQueryDTO); List monthValues = new ArrayList<>(); if (CollectionUtils.isEmpty(monthChartData)) { monthValues = monthChartData.stream().map(item -> item.getV()).collect(Collectors.toList()); result.setMax(monthValues.stream().max(Double::compareTo).get()); result.setMin(monthValues.stream().min(Double::compareTo).get()); } return success(result); } private double getMin(List> dataList) { double result = Double.parseDouble(dataList.get(0).get(1).toString()); for (int i = 0; i < dataList.size() - 1; i++) { if (result > Double.parseDouble(dataList.get(i).get(1).toString())) { result = Double.parseDouble(dataList.get(i).get(1).toString()); } } return result; } private double getMax(List> dataList) { double result = 0; for (int i = 0; i < dataList.size() - 1; i++) { if (result < Double.parseDouble(dataList.get(i).get(1).toString())) { result = Double.parseDouble(dataList.get(i).get(1).toString()); } } return result; } @GetMapping("/adjust-factor") @Operation(summary = "功率因数-调整后的功率因数与无功倒送量") public CommonResult> getPowerAdjustFactor(@RequestParam Map params) { List list = powerAdjustedFactorService.list(params); List dtoList = ConvertUtils.sourceToTarget(list, PowerAdjustedFactorDTO.class); Map result = new HashMap<>(); if (CollectionUtils.isEmpty(list)) { log.info("PowerAdjustedFactor List is empty"); return success(result); } List points = new ArrayList<>(); Map dataMap = new HashMap<>(); for (PowerAdjustedFactorDTO dto : dtoList) { if (StringUtils.isNotBlank(dto.getPointNo())) { points.add(dto.getPointNo()); } } if (!CollectionUtils.isEmpty(points)) { dataMap = dataPointApi.queryPointsRealValue(points); } for (PowerAdjustedFactorDTO powerAdjustedFactorDTO : dtoList) { Double value = dataMap.get(powerAdjustedFactorDTO.getPointNo()) == null ? 0 : Double.parseDouble(dataMap.get(powerAdjustedFactorDTO.getPointNo()).toString()); result.put(powerAdjustedFactorDTO.getName(), value); } return success(result); } @PostMapping("/demand/history") @Operation(summary = "负荷移植-实测需量,有功功率 历史") public CommonResult getPowerDemandHistory(@RequestBody PowerDemandHisReqDTO dto) { log.info("请求参数: {}", JSONObject.toJSONString(dto)); // 参数校验 if (StringUtils.isBlank(dto.getCode())) { return CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST, "code不能为空"); } if (StringUtils.isBlank(dto.getQueryType())) { return CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST, "queryType不能为空"); } PowerDemandEntity powerDemand = powerDemandService.getByCode(dto.getCode()); if (powerDemand == null) { log.info("未找到code对应的数据: {}", dto.getCode()); return success(new PowerHistoryDTO()); } String queryType = dto.getQueryType().toUpperCase(); String pointNo; switch (queryType.toUpperCase()) { case "D": pointNo = powerDemand.getCurDemand(); break; case "P": pointNo = powerDemand.getActivePower(); break; default: throw new IllegalArgumentException("不支持的queryType: " + queryType); } // 默认查最近24小时 Date end = Optional.ofNullable(dto.getEndTime()).orElseGet(() -> { Calendar cal = Calendar.getInstance(); cal.set(Calendar.MILLISECOND, 0); cal.set(Calendar.SECOND, 0); return cal.getTime(); }); Date start = Optional.ofNullable(dto.getStartTime()).orElseGet(() -> { Calendar cal = Calendar.getInstance(); cal.setTime(end); cal.add(Calendar.MINUTE, -1440); // 24小时前 return cal.getTime(); }); // 查询历史数据 ApiPointValueQueryDTO query = new ApiPointValueQueryDTO(); query.setPointNo(pointNo); query.setStart(start); query.setEnd(end); log.info("开始查询实测需量/有功功率历史数据,测点: {}", pointNo); List chartData = dataPointApi.queryPointHistoryValue(query); // 构建返回结果 PowerHistoryDTO result = new PowerHistoryDTO(); result.setCategories(DateUtils.getTimeScale(start, end, 60)); result.setDataList(chartData.stream() .map(pv -> new Object[]{ DateUtils.format(pv.getT(), DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND), pv.getV() }) .collect(Collectors.toList())); return success(result); } }