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 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; @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 nodeName) { List list = powerNetFactorService.listDropdown(nodeName); List result = ConvertUtils.sourceToTarget(list, PowerNetFactorDropdownDTO.class); return success(result); } /** * 判断 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(); calendar.add(Calendar.MONTH, 1); Date end = calendar.getTime(); ApiPointValueQueryDTO apiPointValueQueryDTO = new ApiPointValueQueryDTO(); apiPointValueQueryDTO.setStart(start); apiPointValueQueryDTO.setEnd(end); 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); } @GetMapping("/power/historyData") @Operation(summary = "功率因数-根据nodeName获取最近1440min历史数据,月最大,最小值") public CommonResult getPowerHistoryData(@RequestParam Map params) { PowerNetFactorEntity powerNetFactor = powerNetFactorService.list(params).get(0); PowerHistoryDTO result = new PowerHistoryDTO(); if (powerNetFactor == null) { return success(result); } ApiPointValueQueryDTO apiPointValueQueryDTO = new ApiPointValueQueryDTO(); String pointNo = ""; Date start = null; Date end = null; switch (params.get("queryType").toString()) { case "p": pointNo = powerNetFactor.getCurP(); case "q": pointNo = powerNetFactor.getCurQ(); case "cos": pointNo = powerNetFactor.getCurCos(); } apiPointValueQueryDTO.setPointNo(pointNo); SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); if (params.get("startTime") != null) { try { start = ft.parse(params.get("startTime").toString()); } catch (ParseException e) { throw new RuntimeException(e); } } else { start = new Date(System.currentTimeMillis() - 1440L * 60 * 1000); } apiPointValueQueryDTO.setStart(start); if (params.get("endTime") != null) { try { end = ft.parse(params.get("endTime").toString()); } catch (ParseException e) { throw new RuntimeException(e); } } else { end = new Date(); } apiPointValueQueryDTO.setEnd(end); List chartData = dataPointApi.queryPointHistoryValue(apiPointValueQueryDTO); List> dataList = new ArrayList<>(); for (ApiPointValueDTO dto : chartData) { List data = new ArrayList<>(); String time = ft.format(dto.getT()); double value = dto.getV(); data.add(time); data.add(value); dataList.add(data); } List categories = DateUtils.getTimeScale(start, end, 5); result.setCategories(categories); result.setDataList(dataList); result.setMax(getMax(dataList)); result.setMin(getMin(dataList)); return success(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; } private double getMin(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; } }