package com.gyee.generation.service; import com.gyee.common.contant.ContantXk; import com.gyee.common.model.PointData; import com.gyee.generation.init.CacheContext; import com.gyee.generation.model.auto.*; import com.gyee.generation.service.auto.*; import com.gyee.generation.util.DateUtils; import com.gyee.generation.util.StringUtils; import com.gyee.generation.util.realtimesource.IEdosUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; @Service public class ShutdownService { @Resource private IEdosUtil edosUtil; @Resource private IProEconWindturbineStatusService proEconWindturbineStatusService; @Resource private IProEconShutdownEventService proEconShutdownEventService; @Resource private IProEconShutdownEvent2Service proEconShutdownEvent2Service; @Resource private IProEconInterruptionService proEconInterruptionService; @Resource private IProEconInputOrOutputSpeedService proEconInputOrOutputSpeedService; public static Logger logger = LoggerFactory.getLogger(ShutdownService.class); /// /// 风机状态测点,key为风机编号 /// public Map statusPoints = new HashMap<>(); /// /// 风机功率测点,key为风机编号 /// public Map powerPoints = new HashMap<>(); /// /// 风机当前状态,key为风机编号 /// public Map status = new HashMap<>(); /// /// 保存风机信息,key为风机编号 /// public Map windTurbines = new HashMap<>(); /// /// 风机状态说明,key为状态码,value为状态说明 /// public Map statusDescription = new HashMap<>(); public Date date = new Date(); Map oldStatusMap = new HashMap<>(); Map oldShutdownEvent = new HashMap<>(); Map oldInterrup = new HashMap<>(); //新增shutdownevent2 实时 Map oldShutdownEvent2 = new HashMap<>(); /// /// 风机功率 key为风机编号 /// Map powerpointMap = new HashMap<>();//功率 /// /// 风机风速 key为风机编号 /// Map speedpointMap = new HashMap<>();//风速 /// /// 测风塔风速 key为风场编号 /// Map gzdpointMap = new HashMap<>();//测风塔风速 Map windpowerMap;//风场 public void init() { // statusDescription.put(0, "待机"); // statusDescription.put(1, "并网"); // statusDescription.put(2, "停机"); // statusDescription.put(3, "通讯中断"); // statusDescription.put(4, "维护"); // statusDescription.put(5, "限电"); statusDescription.put(0, "待机"); statusDescription.put(1, "手动停机"); statusDescription.put(2, "正常发电"); statusDescription.put(3, "缺陷降出力"); statusDescription.put(4, "故障停机"); statusDescription.put(5, "故障受累"); statusDescription.put(6, "检修停机"); statusDescription.put(7, "检修受累"); statusDescription.put(8, "限电降出力"); statusDescription.put(9, "限电停机"); statusDescription.put(10, "电网受累"); statusDescription.put(11, "环境受累"); statusDescription.put(12, "通讯中断"); statusDescription.put(13, "设备离线"); windpowerMap = CacheContext.wpmap; List items=new ArrayList<>(); List powerpointList = new ArrayList<>(); List speedpointList = new ArrayList<>(); List wtls= CacheContext.wtls; Map> wtpAimap=CacheContext.wtpAimap; //筛选风机对应测点 wtls.forEach(wt->{ Map windturbinetestingpointnewMap = wtpAimap.get(wt.getId()); if(windturbinetestingpointnewMap.containsKey(ContantXk.MXZT)) { ProBasicEquipmentPoint mxztPoint = windturbinetestingpointnewMap.get(ContantXk.MXZT); items.add(mxztPoint); } if(windturbinetestingpointnewMap.containsKey(ContantXk.CJ_SSGL)) { ProBasicEquipmentPoint ssglPoint = windturbinetestingpointnewMap.get(ContantXk.CJ_SSGL); powerPoints.put(ssglPoint.getNemCode(),ssglPoint); powerpointList.add(ssglPoint); } if(windturbinetestingpointnewMap.containsKey(ContantXk.CJ_SSFS)) { ProBasicEquipmentPoint ssfsPoint = windturbinetestingpointnewMap.get(ContantXk.CJ_SSFS); speedpointList.add(ssfsPoint); } }); //进行测点排序 powerpointList.sort(Comparator.comparing(ProBasicEquipmentPoint::getWindturbineId)); speedpointList.sort(Comparator.comparing(ProBasicEquipmentPoint::getWindturbineId)); for (ProBasicEquipmentPoint item : items) { statusPoints.put(item.getWindturbineId(), item); status.put(item.getWindturbineId(), -1); } windTurbines=CacheContext.wtmap; List gzdpointList =new ArrayList<>(); CacheContext.wpls.forEach(wp->{ Map wppointsmap = CacheContext.wppointmap.get(wp.getId()); if(wppointsmap.containsKey(ContantXk.FCCFTFS70)) { ProBasicPowerstationPoint mxztPoint = wppointsmap.get(ContantXk.FCCFTFS70); gzdpointList.add(mxztPoint); } }); for (ProBasicEquipmentPoint proBasicEquipmentPoint : powerpointList) { if (!powerpointMap.containsKey(proBasicEquipmentPoint.getWindturbineId())) { powerpointMap.put(proBasicEquipmentPoint.getWindturbineId(), proBasicEquipmentPoint); } } for (ProBasicEquipmentPoint proBasicEquipmentPoint : speedpointList) { if (!speedpointMap.containsKey(proBasicEquipmentPoint.getWindturbineId())) { speedpointMap.put(proBasicEquipmentPoint.getWindturbineId(), proBasicEquipmentPoint); } } for (ProBasicPowerstationPoint proBasicPowerstationPoint : gzdpointList) { if (!gzdpointMap.containsKey(proBasicPowerstationPoint.getWindpowerstationId())) { gzdpointMap.put(proBasicPowerstationPoint.getWindpowerstationId(), proBasicPowerstationPoint); } } // List pbmprls=proBasicModelPowerRdService.list().stream() // // .sorted(Comparator.comparing(ProBasicModelPowerRd::getSpeed)).collect(Collectors.toList()); // // // if(!pbmprls.isEmpty()) // { // for(ProBasicModelPowerRd pwpcf:pbmprls) // { // // if(modelPowerMap.containsKey(pwpcf.getId())) // { // Map map =modelPowerMap.get(pwpcf.getId()); // map.put(pwpcf.getSpeed(),pwpcf); // modelPowerMap.put(pwpcf.getId(),map); // }else // { // Map map = new HashMap(); // map.put(pwpcf.getSpeed(),pwpcf); // modelPowerMap.put(pwpcf.getId(),map); // } // // } // } } public void execShutdown() throws Exception { init(); oldStatusMap.clear(); oldShutdownEvent.clear(); oldInterrup.clear(); oldShutdownEvent2.clear(); logger.debug("{0}开始", date); //循环读取所有风机的当前状态,并且给几个缓存字典初始化 for (String key : statusPoints.keySet()) { //取实时状态数据 赋值给status double power = 0; if (powerPoints.containsKey(key)) { power = StringUtils.round(edosUtil.getRealData(powerPoints.get(key).getNemCode()).getPointValueInDouble(),4); } double value = StringUtils.round(edosUtil.getRealData(statusPoints.get(key).getNemCode()).getPointValueInDouble(),4); if (power > 1) { status.put(key,value == 9 ? 1 : (int) value); } else { status.put(key,value == 9 ? 0 : (int) value); } oldStatusMap.put(key, null); oldShutdownEvent.put(key, null); oldInterrup.put(key, null); // 新增 shutdownevent2 实时 oldShutdownEvent2.put(key, null); } //读取oracle中 五种小时数、停机记录、中断记录 //读取数据库存在的恢复时间为NULL的数据 List oldStatusQuery=proEconWindturbineStatusService.list().stream() .filter(i->StringUtils.empty(i.getStartTime())) .sorted(Comparator.comparing(ProEconWindturbineStatus::getStopTime)).collect(Collectors.toList()); for (ProEconWindturbineStatus oldStatus : oldStatusQuery) { if (oldStatusMap.containsKey(oldStatus.getWindturbineId())) { oldStatusMap.put(oldStatus.getWindturbineId(),oldStatus); } } List oldShutdwonQuery=proEconShutdownEventService.list().stream() .filter(i->StringUtils.empty(i.getStartTime())) .sorted(Comparator.comparing(ProEconShutdownEvent::getStopTime)).collect(Collectors.toList()); for (ProEconShutdownEvent shutdown : oldShutdwonQuery) { if (oldShutdownEvent.containsKey(shutdown.getWindturbineId())) { oldShutdownEvent.put(shutdown.getWindturbineId(),shutdown); } } List oldInterrupQuery=proEconInterruptionService.list().stream() .filter(i->StringUtils.empty(i.getStartTime())) .sorted(Comparator.comparing(ProEconInterruption::getStopTime)).collect(Collectors.toList()); for (ProEconInterruption interrup : oldInterrupQuery) { if (oldInterrup.containsKey(interrup.getWindturbineId())) { oldInterrup.put(interrup.getWindturbineId(),interrup); } } // 新增 shutdownevent2 实时 List oldShutdwonQuery2=proEconShutdownEvent2Service.list().stream() .filter(i->StringUtils.empty(i.getStartTime())) .sorted(Comparator.comparing(ProEconShutdownEvent2::getStopTime)).collect(Collectors.toList()); for (ProEconShutdownEvent2 shutdown : oldShutdwonQuery2) { if (oldShutdownEvent2.containsKey(shutdown.getWindturbineId())) { oldShutdownEvent2.put(shutdown.getWindturbineId(),shutdown); } } for (String s : oldStatusMap.keySet()) { ProEconWindturbineStatus item = oldStatusMap.get(s); if (item == null) { //logger.debug("{0}重复加入 风机编号{1}", date,s); ProEconShutdownEvent shutdwonEvent=new ProEconShutdownEvent(); ProEconInterruption interrup=new ProEconInterruption(); //新增 shutdownevent2 实时 ProEconShutdownEvent2 shutdwonEvent2=new ProEconShutdownEvent2(); item = buildWindturbineStatus(s, date, shutdwonEvent, interrup, shutdwonEvent2); proEconWindturbineStatusService.save(item); proEconShutdownEventService.save(shutdwonEvent); proEconInterruptionService.save(interrup); // 新增 shutdownevent2 实时 //20分钟以内的报警数据 Date dtbegin = DateUtils.addMinutes(shutdwonEvent2.getStopTime(),-15); Date dtend = shutdwonEvent2.getStopTime(); Optional olditemo= proEconShutdownEvent2Service.list().stream() .filter(i -> i.getWindturbineId().equals(s) && (i.getStartTime().compareTo(dtbegin) == 0 || i.getStartTime().after(dtbegin)) && (i.getStartTime().compareTo(dtend) == 0 || i.getStartTime().before(dtend)) ).min(Comparator.comparing(ProEconShutdownEvent2::getStartTime)); ProEconShutdownEvent2 lditem; if (!olditemo.isPresent()) { proEconShutdownEvent2Service.save(shutdwonEvent2); } else { lditem=olditemo.get(); lditem.setStartTime(null); if (!oldShutdownEvent2.containsKey(lditem.getWindturbineId())) oldShutdownEvent2.put(lditem.getWindturbineId(), lditem); } continue; } Calendar c=Calendar.getInstance(); c.setTime(date); if (c.get(Calendar.HOUR_OF_DAY) == 0 &&c.get(Calendar.MINUTE) == 0) { logger.debug("{0}--整点操作--{1}", s, date); updateAndAddStatus( item); } else if (!Objects.equals(item.getSatusCode(), status.get(s))) { updateAndAddStatus(item); // #region 切入切出风速 if (item.getSatusCode() == 0 && status.get(s) == 2) { ProEconInputOrOutputSpeed input = new ProEconInputOrOutputSpeed(); input.setWindturbineId(s); input.setWindpowerstationId(windTurbines.get(s).getWindpowerstationId()); input.setProjectId(windTurbines.get(s).getProjectId()); input.setLineId(windTurbines.get(s).getLineId()); input.setRecordDate(date); input.setInputOrOutput(1); if (speedpointMap.containsKey(s)) { double value =edosUtil.getRealData(speedpointMap.get(s).getNemCode()).getPointValueInDouble(); input.setSpeed(value); } proEconInputOrOutputSpeedService.save(input); } else if (item.getSatusCode() == 1 && status.get(s)== 0) { ProEconInputOrOutputSpeed input = new ProEconInputOrOutputSpeed(); input.setWindturbineId(s); input.setWindpowerstationId(windTurbines.get(s).getWindpowerstationId()); input.setProjectId(windTurbines.get(s).getProjectId()); input.setLineId(windTurbines.get(s).getLineId()); input.setRecordDate(date); input.setInputOrOutput(0); if (speedpointMap.containsKey(s)) { double value =edosUtil.getRealData(speedpointMap.get(s).getNemCode()).getPointValueInDouble(); input.setSpeed(value); } proEconInputOrOutputSpeedService.save(input); } } updateAndAddStatus2(item); } logger.debug("{0}-------结束", date); } /// /// 计算损失电量 /// /// /// private void updateAndAddStatus2(ProEconWindturbineStatus status) throws Exception { Integer oldStatus = status.getSatusCode(); if (oldStatus == 4 || oldStatus == 6) { ProEconShutdownEvent ose = oldShutdownEvent.get(status.getWindturbineId()); if (ose != null) { Double gc = calcLossPower(ose.getWindturbineId(), ose.getStopTime(), date); ose.setLossPower(gc); } // 新增 shutdownevent2 实时 ProEconShutdownEvent2 ose2 = oldShutdownEvent2.get(status.getWindturbineId()); if (ose2 != null) { Double gc = calcLossPower(ose2.getWindturbineId(), ose2.getStopTime(), date); ose2.setLossPower(gc); } } } private void updateAndAddStatus( ProEconWindturbineStatus status) throws Exception { status.setStartTime(date); List speedDataList1; if (windTurbines.get(status.getWindturbineId()).getWindpowerstationId().contains("GDC")) { String point=gzdpointMap.get(windTurbines.get(status.getWindturbineId()).getWindpowerstationId()).getNemCode(); speedDataList1 =edosUtil.getHistoryDatasSnap(point,status.getStopTime().getTime()/1000,status.getStartTime().getTime()/1000); } else { String point=speedpointMap.get(status.getWindturbineId()).getNemCode(); speedDataList1 =edosUtil.getHistoryDatasSnap(point,status.getStopTime().getTime()/1000,status.getStartTime().getTime()/1000); } if (speedDataList1 != null && speedDataList1.size() > 0) { status.setSpeed(speedDataList1.get(0).getPointValueInDouble()); DoubleSummaryStatistics summaryStatistics=speedDataList1.stream().mapToDouble(PointData::getPointValueInDouble).summaryStatistics(); status.setAvgSpeed(summaryStatistics.getAverage()); } else { status.setSpeed(0.0); status.setAvgSpeed(0.0); } double timehour=DateUtils.hoursDiff2(date,status.getStopTime()); status.setStopHours(timehour); ProEconShutdownEvent shutdwonEvent = new ProEconShutdownEvent(); ProEconInterruption interrup = new ProEconInterruption(); // #region 新增 shutdownevent2 实时 ProEconShutdownEvent2 shutdwonEvent2 = new ProEconShutdownEvent2(); ProEconWindturbineStatus newStatusItem = buildWindturbineStatus(status.getWindturbineId(), date, shutdwonEvent, interrup, shutdwonEvent2); proEconWindturbineStatusService.save(newStatusItem); Integer oldStatus = status.getSatusCode(); Integer currentStatus = this.status.get(status.getWindturbineId()); if (currentStatus == 4 || currentStatus == 6) { if (oldStatus == 0 || oldStatus == 1 || oldStatus == 12) { proEconShutdownEventService.save(shutdwonEvent); } } if (currentStatus == 12 && oldStatus != 12) { proEconInterruptionService.save(interrup); } // 新增 shutdownevent2 实时 if (currentStatus == 4 || currentStatus == 6) { if (oldStatus == 0 || oldStatus == 1 || oldStatus == 12) { Date dtbegin = DateUtils.addMinutes(shutdwonEvent2.getStopTime(),-30); Date dtend = shutdwonEvent2.getStopTime(); String windTurbineId = shutdwonEvent2.getWindturbineId(); Optional olditem= proEconShutdownEvent2Service.list().stream() .filter(i -> i.getWindturbineId().equals(windTurbineId) && (i.getStartTime().compareTo(dtbegin) == 0 || i.getStartTime().after(dtbegin)) && (i.getStartTime().compareTo(dtend) == 0 || i.getStartTime().before(dtend)) ).min(Comparator.comparing(ProEconShutdownEvent2::getStartTime)); ProEconShutdownEvent2 temp; if (!olditem.isPresent()) { proEconShutdownEvent2Service.save(shutdwonEvent2); } else { temp=olditem.get(); temp.setStartTime(null); if (!oldShutdownEvent2.containsKey(temp.getWindturbineId())) oldShutdownEvent2.put(temp.getWindturbineId(), temp); } } } if (oldStatus == 4 || oldStatus == 6) { if (currentStatus == 0 || currentStatus == 1 || currentStatus == 12) { ProEconShutdownEvent ose = oldShutdownEvent.get(status.getWindturbineId()); if (ose != null) { ose.setStartTime(date); timehour=DateUtils.hoursDiff2(date,ose.getStopTime()); ose.setStopHours(timehour); if (!ose.getStoptypeId().equals("wh")) { String s =newMethod( status.getWindturbineId(), DateUtils.addMinutes(ose.getStopTime(),-5), date); if (StringUtils.notEmp(s)) { ose.setStoptypeId(s); } } //Double gc = calcLossPower(ose.WINDTURBINEID, ose.STOPTIME.Value, ose.STARTTIME.Value, ose.STOPHOURS.Value, entities); //ose.LOSSPOWER = gc; } // 新增 shutdownevent2 实时 ProEconShutdownEvent2 ose2 = oldShutdownEvent2.get(status.getWindturbineId()); if (ose2 != null ) { ose2.setStartTime(date); timehour=DateUtils.hoursDiff2(date,ose2.getStopTime()); ose2.setStopHours(timehour); if (ose!=null && !ose.getStoptypeId().equals("wh")) { ose2.setStopTypeId(ose.getStoptypeId()); } } } } if (oldStatus == 12 && currentStatus != 12) { ProEconInterruption item = oldInterrup.get(status.getWindturbineId()); if (item != null) { item.setStartTime(date); timehour=DateUtils.hoursDiff2(date,item.getStopTime()); item.setStopHours(timehour); } } } private Double calcLossPower(String windturbineId, Date startDate, Date endDate) throws Exception { double result = 0.0; Map> wtpAimap = CacheContext.wtpAimap; Map wtpointmap=wtpAimap.get(windturbineId); Calendar c1=Calendar.getInstance(); c1.setTime(startDate); Calendar c2=Calendar.getInstance(); c2.setTime(endDate); //判定限电是否跨年 if(endDate.after(startDate) && c1.get(Calendar.YEAR)==c2.get(Calendar.YEAR)) { //年故障损失电量 if(wtpointmap.containsKey(ContantXk.NGZSSDL) ) { double beginvalue; double endvalue; List pointid=new ArrayList<>(); pointid.add(wtpointmap.get(ContantXk.NGZSSDL).getNemCode()); List xdbegin=edosUtil.getHistMatrix(pointid,startDate.getTime()/1000); List xdend=edosUtil.getHistMatrix(pointid,endDate.getTime()/1000); if(xdbegin.size()==1 && xdend.size()==1) { beginvalue=xdbegin.get(0).getPointValueInDouble(); endvalue=xdend.get(0).getPointValueInDouble(); if (endvalue > beginvalue) { result =result+(endvalue - beginvalue); } } } }else { Calendar c=Calendar.getInstance(); c.setTime(DateUtils.truncDay(startDate)); c.add(Calendar.DAY_OF_MONTH,1); //获得1月1日零点值 Date endtime=c.getTime(); //年故障损失电量 if(wtpointmap.containsKey(ContantXk.NGZSSDL) ) { double beginvalue; double endvalue; List pointid=new ArrayList<>(); pointid.add(wtpointmap.get(ContantXk.NGZSSDL).getNemCode()); List xdbegin=edosUtil.getHistMatrix(pointid,startDate.getTime()/1000); List xdend=edosUtil.getHistMatrix(pointid,endtime.getTime()/1000); if(xdbegin.size()==1 && xdend.size()==1) { beginvalue=xdbegin.get(0).getPointValueInDouble(); endvalue=xdend.get(0).getPointValueInDouble(); if (endvalue > beginvalue) { result =result+(endvalue - beginvalue); } } } //日故障损失电量 if(wtpointmap.containsKey(ContantXk.NGZSSDL) ) { double endvalue; List pointid=new ArrayList<>(); pointid.add(wtpointmap.get(ContantXk.NGZSSDL).getNemCode()); List xdend=edosUtil.getHistMatrix(pointid,startDate.getTime()/1000); if(xdend.size()==1) { endvalue=xdend.get(0).getPointValueInDouble(); if (endvalue > 0) { result =result+endvalue; } } } } return result; } // 新增 shutdownevent2 实时 private ProEconWindturbineStatus buildWindturbineStatus(String windturbineId, Date date, ProEconShutdownEvent shutdwonEvent, ProEconInterruption interrup, ProEconShutdownEvent2 shutdwonEvent2) { ProEconWindturbineStatus retValue = new ProEconWindturbineStatus(); retValue.setProjectId(windTurbines.get(windturbineId).getProjectId()); retValue.setSatusCode(status.get(windturbineId)); retValue.setStatusDesc(statusDescription.get(status.get(windturbineId))); retValue.setStopTime(date); retValue.setWindpowerstationId(windTurbines.get(windturbineId).getWindpowerstationId()); retValue.setWindturbineId(windturbineId); Integer currentStatus = status.get(windturbineId); if (currentStatus == 4 || currentStatus == 6) { shutdwonEvent.setId(StringUtils.getUUID()); shutdwonEvent.setProjectId(retValue.getProjectId()); shutdwonEvent.setStatusCode(currentStatus); shutdwonEvent.setStopTime(date); shutdwonEvent.setWindpowerstationId(retValue.getWindpowerstationId()); shutdwonEvent.setWindturbineId(windturbineId); shutdwonEvent2.setId(StringUtils.getUUID()); shutdwonEvent2.setProjectId(retValue.getProjectId()); shutdwonEvent2.setStatusCode(currentStatus); shutdwonEvent2.setStopTime(date); shutdwonEvent2.setWinpowerstationId(retValue.getWindpowerstationId()); shutdwonEvent2.setWindturbineId(windturbineId); if (currentStatus == 4) { Date begin =DateUtils.addMinutes(date,-5); Date end = DateUtils.addMinutes(date,5); shutdwonEvent.setStoptypeId("gzbmq"); shutdwonEvent2.setStopTypeId("gzbmq"); //读取报警记录表前后五分钟数据,选取第一个报警报警类型 String s =newMethod( windturbineId, begin, end); if (StringUtils.notEmp(s)) { shutdwonEvent.setStoptypeId(s); shutdwonEvent2.setStopTypeId(s); } } else { shutdwonEvent.setStoptypeId("wh"); shutdwonEvent2.setStopTypeId("wh"); } retValue.setShutdownEventId(shutdwonEvent.getId()); } if (currentStatus == 12) { interrup.setProjectId(retValue.getProjectId()); interrup.setStopTime(date); interrup.setWindpowerstationId(retValue.getWindpowerstationId()); interrup.setWindturbineId(windturbineId); } return retValue; } //TODO-SL 需要添加报警记录关联停机事件方法 /** * */ private String newMethod( String windturbineId, Date begin, Date end) { String result = ""; return result; } }