13 changed files with 347 additions and 42 deletions
@ -0,0 +1,43 @@ |
|||||||
|
package com.hnac.hzims.equipment.entity; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||||
|
import io.swagger.annotations.ApiModel; |
||||||
|
import io.swagger.annotations.ApiModelProperty; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.EqualsAndHashCode; |
||||||
|
import org.springblade.core.tenant.mp.TenantEntity; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* @author ysj |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@EqualsAndHashCode(callSuper = true) |
||||||
|
@TableName("hzims_em_start_stop_duration") |
||||||
|
@ApiModel(value = "设备开停机时长", description = "单日开停机记录") |
||||||
|
public class StartStopDurationEntity extends TenantEntity { |
||||||
|
|
||||||
|
@ApiModelProperty(value = "站点编码") |
||||||
|
private String stationId; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "站点名称") |
||||||
|
private String stationName; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "设备编号") |
||||||
|
private String deviceCode; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "设备名称") |
||||||
|
private String deviceName; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "日期") |
||||||
|
private String strDay; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "开机时长") |
||||||
|
private Double startDuration; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "停机时长") |
||||||
|
private Double stopDuration; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package com.hnac.hzims.operational.station.vo; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize; |
||||||
|
import com.fasterxml.jackson.databind.ser.std.NullSerializer; |
||||||
|
import io.swagger.annotations.ApiModel; |
||||||
|
import io.swagger.annotations.ApiModelProperty; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.EqualsAndHashCode; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* @author ysj |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@EqualsAndHashCode |
||||||
|
@ApiModel("开停机数据对象") |
||||||
|
public class StartStopDurationRecordVo { |
||||||
|
|
||||||
|
@ApiModelProperty(value = "时间") |
||||||
|
@JsonSerialize(nullsUsing = NullSerializer.class) |
||||||
|
private String ts; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "值") |
||||||
|
@JsonSerialize(nullsUsing = NullSerializer.class) |
||||||
|
private String val; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "质量") |
||||||
|
@JsonSerialize(nullsUsing = NullSerializer.class) |
||||||
|
private String q; |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package com.hnac.hzims.scheduled.mapper.equipment; |
||||||
|
|
||||||
|
|
||||||
|
import com.hnac.hzims.equipment.entity.StartStopDurationEntity; |
||||||
|
import org.apache.ibatis.annotations.Param; |
||||||
|
import org.springblade.core.datascope.mapper.UserDataScopeBaseMapper; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author ysj |
||||||
|
*/ |
||||||
|
public interface StartStopDurationMapper extends UserDataScopeBaseMapper<StartStopDurationEntity> { |
||||||
|
|
||||||
|
void deleteThisDayStartStopRecord(@Param(value = "strDay") String strDay); |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
package com.hnac.hzims.scheduled.service.equipment; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService; |
||||||
|
import com.hnac.hzims.equipment.entity.StartStopDurationEntity; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author ysj |
||||||
|
*/ |
||||||
|
public interface StartStopDurationService extends IService<StartStopDurationEntity> { |
||||||
|
|
||||||
|
void thisDayStartStopRecord(String param); |
||||||
|
} |
@ -0,0 +1,223 @@ |
|||||||
|
package com.hnac.hzims.scheduled.service.equipment.impl; |
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import com.alibaba.fastjson.TypeReference; |
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS; |
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
||||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder; |
||||||
|
import com.hnac.hzims.equipment.entity.StartStopDurationEntity; |
||||||
|
import com.hnac.hzims.equipment.vo.EminfoAndEmParamVo; |
||||||
|
import com.hnac.hzims.operational.main.constant.HomePageConstant; |
||||||
|
import com.hnac.hzims.operational.station.entity.StationEntity; |
||||||
|
import com.hnac.hzims.operational.station.vo.StartStopDurationRecordVo; |
||||||
|
import com.hnac.hzims.scheduled.mapper.equipment.StartStopDurationMapper; |
||||||
|
import com.hnac.hzims.scheduled.service.equipment.StartStopDurationService; |
||||||
|
import com.hnac.hzims.scheduled.service.operation.station.StationService; |
||||||
|
import com.hnac.hzinfo.datasearch.PointData; |
||||||
|
import com.hnac.hzinfo.datasearch.history.IHistoryDataSearchClient; |
||||||
|
import com.hnac.hzinfo.datasearch.history.OriginalDataQuery; |
||||||
|
import com.hnac.hzinfo.sdk.core.response.HzPage; |
||||||
|
import com.hnac.hzinfo.sdk.core.response.Result; |
||||||
|
import com.hnac.hzinfo.sdk.v5.device.DeviceDataClient; |
||||||
|
import com.hnac.hzinfo.sdk.v5.device.source.dto.HisDeviceSourceDataDTO; |
||||||
|
import com.hnac.hzinfo.sdk.v5.device.source.dto.HisFacSourceDataDTO; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.RequiredArgsConstructor; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.apache.commons.collections4.MapUtils; |
||||||
|
import org.springblade.core.tool.api.R; |
||||||
|
import org.springblade.core.tool.utils.CollectionUtil; |
||||||
|
import org.springblade.core.tool.utils.DateUtil; |
||||||
|
import org.springblade.core.tool.utils.ObjectUtil; |
||||||
|
import org.springblade.core.tool.utils.StringUtil; |
||||||
|
import org.springframework.beans.factory.annotation.Value; |
||||||
|
import org.springframework.data.redis.core.RedisTemplate; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import java.math.BigDecimal; |
||||||
|
import java.math.RoundingMode; |
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.time.format.DateTimeFormatter; |
||||||
|
import java.util.*; |
||||||
|
import java.util.concurrent.ExecutorService; |
||||||
|
import java.util.concurrent.LinkedBlockingQueue; |
||||||
|
import java.util.concurrent.ThreadPoolExecutor; |
||||||
|
import java.util.concurrent.TimeUnit; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author ysj |
||||||
|
*/ |
||||||
|
@RequiredArgsConstructor |
||||||
|
@Service |
||||||
|
@Slf4j |
||||||
|
@DS("equipment") |
||||||
|
public class StartStopDurationServiceImpl extends ServiceImpl<StartStopDurationMapper, StartStopDurationEntity> implements StartStopDurationService { |
||||||
|
|
||||||
|
private final StationService stationService; |
||||||
|
|
||||||
|
private final DeviceDataClient deviceDataClient; |
||||||
|
|
||||||
|
private final RedisTemplate redisTemplate; |
||||||
|
|
||||||
|
@Value("${hzims.equipment.emInfo.emInfoList}") |
||||||
|
public String device_cache_cofig_final; |
||||||
|
|
||||||
|
private static final ExecutorService pool = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(256), new ThreadFactoryBuilder().setNameFormat("device-start-stop-duration-pool-%d").build() , new ThreadPoolExecutor.CallerRunsPolicy()); |
||||||
|
|
||||||
|
/** |
||||||
|
* 单日开停机记录 |
||||||
|
* @param param |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void thisDayStartStopRecord(String param) { |
||||||
|
// 查询水电站点
|
||||||
|
List<StationEntity> stations = stationService.list(Wrappers.<StationEntity>lambdaQuery(). |
||||||
|
eq(StationEntity::getType, HomePageConstant.HYDROPOWER) |
||||||
|
); |
||||||
|
|
||||||
|
// 查询设备信息
|
||||||
|
List<EminfoAndEmParamVo> eminfos = JSONObject.parseObject(redisTemplate.opsForValue().get(device_cache_cofig_final).toString(), new TypeReference<List<EminfoAndEmParamVo>>() {}); |
||||||
|
|
||||||
|
// 查询时间
|
||||||
|
Calendar calendar = Calendar.getInstance(); |
||||||
|
Date end = calendar.getTime(); |
||||||
|
calendar.add(Calendar.HOUR_OF_DAY,-calendar.get(Calendar.HOUR_OF_DAY)); |
||||||
|
calendar.add(Calendar.MINUTE, -calendar.get(Calendar.MINUTE)); |
||||||
|
calendar.add(Calendar.SECOND, -calendar.get(Calendar.SECOND)); |
||||||
|
Date start = calendar.getTime(); |
||||||
|
|
||||||
|
// 删除当日计算开关机记录
|
||||||
|
this.baseMapper.deleteThisDayStartStopRecord(DateUtil.format(start,DateUtil.PATTERN_DATETIME)); |
||||||
|
|
||||||
|
// 遍历站点记录当日开停机时间
|
||||||
|
stations.forEach(station->{ |
||||||
|
if(CollectionUtil.isEmpty(eminfos)){ |
||||||
|
return; |
||||||
|
} |
||||||
|
List<EminfoAndEmParamVo> devices = eminfos.stream().filter(device -> device.getCreateDept().equals(station.getRefDept())).collect(Collectors.toList()); |
||||||
|
if(CollectionUtil.isEmpty(devices)){ |
||||||
|
return; |
||||||
|
} |
||||||
|
// 遍历设备
|
||||||
|
devices.forEach(device->{ |
||||||
|
// 设备开关机状态监测点
|
||||||
|
Map<String,String> point = device.getPoint(); |
||||||
|
if(MapUtils.isEmpty(point)){ |
||||||
|
return; |
||||||
|
} |
||||||
|
// 监测点
|
||||||
|
String realId = point.get(HomePageConstant.START_STOP_STATUS); |
||||||
|
if(StringUtil.isBlank(realId)){ |
||||||
|
return; |
||||||
|
} |
||||||
|
// 查询时间范围开关机监测点历史数据
|
||||||
|
HisDeviceSourceDataDTO source = new HisDeviceSourceDataDTO(); |
||||||
|
source.setProjectId(station.getCode()); |
||||||
|
source.setDeviceCode(device.getEmCode()); |
||||||
|
source.setAttrSignages(Collections.singletonList(HomePageConstant.START_STOP_STATUS)); |
||||||
|
source.setBeginTime(LocalDateTime.parse(DateUtil.format(new Date(), DateUtil.format(start,DateUtil.PATTERN_DATETIME)), DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME))); |
||||||
|
source.setFinishTime(LocalDateTime.parse(DateUtil.format(new Date(), DateUtil.format(end,DateUtil.PATTERN_DATETIME)), DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME))); |
||||||
|
source.setIsPage(false); |
||||||
|
source.setCurrent(1); |
||||||
|
source.setPageSize(100000); |
||||||
|
Result<List<Map<String, Object>>> sources = deviceDataClient.hisDeviceSourceData(source); |
||||||
|
if(!sources.isSuccess() || CollectionUtil.isEmpty(sources.getData())){ |
||||||
|
return; |
||||||
|
} |
||||||
|
// 相邻数据处理
|
||||||
|
List<StartStopDurationRecordVo> adjacents = this.adjacents(sources.getData()); |
||||||
|
// 开机时长
|
||||||
|
long runTimes = this.runTimes(adjacents,start,end); |
||||||
|
StartStopDurationEntity duration = new StartStopDurationEntity(); |
||||||
|
duration.setTenantId(station.getTenantId()); |
||||||
|
duration.setCreateDept(station.getRefDept()); |
||||||
|
duration.setCreateUser(station.getCreateUser()); |
||||||
|
duration.setUpdateUser(station.getUpdateUser()); |
||||||
|
duration.setStationId(station.getCode()); |
||||||
|
duration.setStationName(station.getName()); |
||||||
|
duration.setDeviceCode(device.getEmCode()); |
||||||
|
duration.setDeviceName(device.getName()); |
||||||
|
duration.setStartDuration(BigDecimal.valueOf(runTimes / (1000 * 60 * 60.00)).setScale(2, RoundingMode.HALF_UP).doubleValue()); |
||||||
|
duration.setStopDuration(BigDecimal.valueOf((end.getTime() - start.getTime() - runTimes) / (1000 * 60 * 60.00)).setScale(2, RoundingMode.HALF_UP).doubleValue()); |
||||||
|
duration.setStrDay(DateUtil.format(start,DateUtil.PATTERN_DATETIME)); |
||||||
|
this.save(duration); |
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 过滤相邻开关机状态相同数据 |
||||||
|
* @param sources |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private List<StartStopDurationRecordVo> adjacents(List<Map<String, Object>> sources) { |
||||||
|
Map<String, Object> map = sources.get(0); |
||||||
|
if (MapUtils.isEmpty(map) || !map.containsKey(HomePageConstant.START_STOP_STATUS) || ObjectUtil.isEmpty(map.get(HomePageConstant.START_STOP_STATUS))) { |
||||||
|
return new ArrayList<>(); |
||||||
|
} |
||||||
|
List<StartStopDurationRecordVo> records = JSONObject.parseArray(JSONObject.toJSONString(map.get(HomePageConstant.START_STOP_STATUS)),StartStopDurationRecordVo.class); |
||||||
|
if(CollectionUtil.isEmpty(records)){ |
||||||
|
return new ArrayList<>(); |
||||||
|
} |
||||||
|
// 遍历数据
|
||||||
|
List<StartStopDurationRecordVo> result = new ArrayList<>(); |
||||||
|
for(int i = 0; i< records.size() ; i++){ |
||||||
|
// 第一个数据保存下来
|
||||||
|
if(i == 0){ |
||||||
|
result.add(records.get(i)); |
||||||
|
continue; |
||||||
|
} |
||||||
|
// 遍历数据状态
|
||||||
|
String value = records.get(i).getVal(); |
||||||
|
if(StringUtil.isBlank(value)){ |
||||||
|
continue; |
||||||
|
} |
||||||
|
// 上一条数据状态
|
||||||
|
String up_value = records.get(i-1).getVal(); |
||||||
|
if(value.equals(up_value)){ |
||||||
|
continue; |
||||||
|
} |
||||||
|
result.add(records.get(i)); |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 获取运行时长 |
||||||
|
* @param result |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private long runTimes(List<StartStopDurationRecordVo> result,Date startDate,Date endDate) { |
||||||
|
if(result.size() == 1){ |
||||||
|
// 一直开机
|
||||||
|
if(HomePageConstant.OFF_COMPLEX.equals(result.get(0).getVal()) || HomePageConstant.OFF.equals(result.get(0).getVal())){ |
||||||
|
return endDate.getTime() - startDate.getTime(); |
||||||
|
} |
||||||
|
// 一直关机
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
long time=0; |
||||||
|
// 遍历累计开机时长
|
||||||
|
for(int i = 0; i< result.size() ; i++){ |
||||||
|
// 记录为开机状态 就计算到下次关机的时间差
|
||||||
|
if(HomePageConstant.ON.equals(result.get(i).getVal())){ |
||||||
|
continue; |
||||||
|
} |
||||||
|
Date endTime,startTime = DateUtil.parse(result.get(i).getTs(), "yyyy-MM-dd HH:mm:ss.sss"); |
||||||
|
// 遍历至最后一条数据,累计至当前时间
|
||||||
|
if(i == result.size() - 1){ |
||||||
|
endTime = endDate; |
||||||
|
} |
||||||
|
else { |
||||||
|
endTime = DateUtil.parse(result.get(i+1).getTs(), "yyyy-MM-dd HH:mm:ss.sss"); |
||||||
|
} |
||||||
|
time += endTime.getTime() - startTime.getTime(); |
||||||
|
} |
||||||
|
return time; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,9 +0,0 @@ |
|||||||
package com.hnac.hzims.scheduled.service.startstop; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author ysj |
|
||||||
*/ |
|
||||||
public interface StratStopService { |
|
||||||
|
|
||||||
void thisDayStartStopRecord(String param); |
|
||||||
} |
|
@ -1,24 +0,0 @@ |
|||||||
package com.hnac.hzims.scheduled.service.startstop.impl; |
|
||||||
|
|
||||||
import com.hnac.hzims.scheduled.service.startstop.StratStopService; |
|
||||||
import lombok.RequiredArgsConstructor; |
|
||||||
import lombok.extern.slf4j.Slf4j; |
|
||||||
import org.springframework.stereotype.Service; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author ysj |
|
||||||
*/ |
|
||||||
@Service |
|
||||||
@RequiredArgsConstructor |
|
||||||
@Slf4j |
|
||||||
public class StartStopServiceImpl implements StratStopService { |
|
||||||
|
|
||||||
/** |
|
||||||
* 单日开停机记录 |
|
||||||
* @param param |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public void thisDayStartStopRecord(String param) { |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,8 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > |
||||||
|
<mapper namespace="com.hnac.hzims.scheduled.mapper.equipment.StartStopDurationMapper"> |
||||||
|
|
||||||
|
<delete id="deleteThisDayStartStopRecord"> |
||||||
|
delete from hzims_em_start_stop_duration where STR_DAY = #{strDay} |
||||||
|
</delete> |
||||||
|
</mapper> |
Loading…
Reference in new issue