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