package com.qianwen.mdc.collect.service;
|
|
import java.time.LocalDateTime;
|
import java.time.ZoneId;
|
import java.util.ArrayList;
|
import java.util.Collection;
|
import java.util.Collections;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Map.Entry;
|
import java.util.stream.Collectors;
|
|
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
|
import org.apache.iotdb.tsfile.write.record.Tablet;
|
import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
|
import com.google.common.collect.Lists;
|
import com.qianwen.core.tool.utils.Func;
|
import com.qianwen.core.tool.utils.SpringUtil;
|
import com.qianwen.mdc.collect.cache.WorkstationCache;
|
import com.qianwen.mdc.collect.config.IotDBSessionConfig;
|
import com.qianwen.mdc.collect.constants.CommonConstant;
|
import com.qianwen.mdc.collect.constants.IOTDBConstant;
|
import com.qianwen.mdc.collect.dto.CalendarShiftInfoDTO;
|
import com.qianwen.mdc.collect.dto.WorkstationDTO;
|
import com.qianwen.mdc.collect.entity.iotdb.DeviceState;
|
import com.qianwen.mdc.collect.enums.FeedbackTimePointEnum;
|
import com.qianwen.mdc.collect.mapper.mgr.CalendarMapper;
|
import com.qianwen.mdc.collect.utils.LocalDateTimeUtils;
|
|
import cn.hutool.core.date.DatePattern;
|
import cn.hutool.core.date.DateTime;
|
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
|
@Service
|
public class DeviceStateFixPointService{
|
private static final Logger log = LoggerFactory.getLogger(DeviceStateFixPointService.class);
|
|
@Autowired
|
private CalendarMapper calendarMapper;
|
@Autowired
|
private WorkstationCache workstationCache;
|
@Autowired
|
private IotDBCommonService iotDBCommonService;
|
@Autowired
|
private IotDBSessionConfig iotdbConfig;
|
|
/**
|
* 加入固定点,原workStationStateFixPoint
|
* @param dateTime 打固定点的日期
|
* @param includeWorkstationIds 指定打固定点的工位id,全都打点传null
|
*/
|
public void deviceStateFixPoint(DateTime dateTime, List<String> includeWorkstationIds) {
|
List<DeviceState> result;
|
|
Map<String, WorkstationDTO> workStations = workstationCache.getWorkstations();
|
if (ObjectUtil.isEmpty(workStations)) {
|
return;
|
}
|
Collection<WorkstationDTO> values = workStations.values();
|
|
if (ObjectUtil.isNotEmpty(includeWorkstationIds)) {
|
values = values.stream().filter(item -> includeWorkstationIds.contains(item.getId().toString())).collect(Collectors.toList());
|
}
|
List<String> calendarCodeList = workStations.values().stream().map(WorkstationDTO::getCalendarCode).distinct().filter(Func::isNotEmpty).collect(Collectors.toList());
|
|
Map<String, List<CalendarShiftInfoDTO>> shiftMap ;
|
String formatDateTime = DateUtil.formatDate(dateTime);
|
if (Func.isNotEmpty(calendarCodeList)) {
|
List<CalendarShiftInfoDTO> calendarShiftInfoDTOList = calendarMapper.getCalendarShiftInfo(calendarCodeList, DateUtil.year(dateTime), formatDateTime);
|
shiftMap = calendarShiftInfoDTOList.stream().collect(Collectors.groupingBy(CalendarShiftInfoDTO::getCode));
|
}else {
|
shiftMap = Collections.emptyMap();
|
}
|
List<DeviceState> res = Lists.newArrayList();
|
for (WorkstationDTO workstationDTO : values) {
|
|
result = Lists.newArrayList();
|
List<CalendarShiftInfoDTO> calendarShiftList = shiftMap.getOrDefault(workstationDTO.getCalendarCode(), Collections.singletonList(new CalendarShiftInfoDTO().setCode("0").setCalendarDay(formatDateTime).setFactoryYear(Integer.valueOf(DateUtil.year(dateTime))).setFactoryWeek(LocalDateTimeUtils.getWeek(dateTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate())).setFactoryMonth(Integer.valueOf(DateUtil.month(dateTime) + 1)).setFactoryDate(formatDateTime).setStartTime(DateUtil.beginOfDay(dateTime)).setShiftIndex(CommonConstant.DEFAULT_SHIFT_INDEX).setShiftTimeType(CommonConstant.DEFAULT_SHIFT_TYPE)));
|
if (shiftMap.containsKey(workstationDTO.getCalendarCode())) {
|
result = getNoDefaultShift24HourPointDTOS(workstationDTO.getId(), workstationDTO.getCalendarCode(), dateTime);
|
} else {
|
result = getDefaultShift24HourPointDTOS(workstationDTO.getId(), workstationDTO.getCalendarCode(), calendarShiftList.get(0));
|
}
|
|
//将生产日历中的时间节点加入固定点
|
for (int i = 0; i < calendarShiftList.size(); i++) {
|
//DeviceState workstationState = WorkstationStateConvert.INSTANCE.convert(list.get(i));
|
CalendarShiftInfoDTO calendarShiftDTO = calendarShiftList.get(i);
|
|
DeviceState deviceState = new DeviceState();
|
|
deviceState.setIsSync(false);
|
deviceState.setIsFixPoint(true);
|
deviceState.setValueCollect(0);
|
deviceState.setRps(0);
|
deviceState.setWcs(0);
|
deviceState.setWorkstationId(workstationDTO.getId());
|
deviceState.setTime(Long.valueOf(calendarShiftDTO.getStartTime().getTime()));
|
deviceState.setIsDeleted(Boolean.FALSE);
|
deviceState.setFeedbackPointType(FeedbackTimePointEnum.NO_FEED_BACK_POINT.getValue());
|
deviceState.setCalendarCode(workstationDTO.getCalendarCode());
|
|
String factoryDate = calendarShiftDTO.getFactoryDate();
|
String[] split = Func.split(factoryDate, "-");
|
deviceState.setFactoryDate(Integer.valueOf(String.join("", split)));
|
deviceState.setFactoryYear(calendarShiftDTO.getFactoryYear());
|
deviceState.setFactoryMonth(calendarShiftDTO.getFactoryMonth());
|
deviceState.setFactoryWeek(calendarShiftDTO.getFactoryWeek());
|
|
deviceState.setShiftIndex(calendarShiftDTO.getShiftIndex());
|
deviceState.setShiftTimeType(calendarShiftDTO.getShiftTimeType());
|
|
|
buildDefaultFactoryDay(dateTime, deviceState);
|
|
result.add(deviceState);
|
}
|
res.addAll(result);
|
}
|
|
/*
|
Map<Long, List<DeviceState>> collect = res.stream().distinct().collect(Collectors.groupingBy(DeviceState::getWorkstationId));
|
|
collect.forEach((k, v) -> this.workstationStateMapper.batchSave(k, v));
|
*/
|
//res.stream().distinct().collect(Collectors.toList())
|
saveDeviceStates(res);
|
}
|
|
|
/**
|
* 保存状态固定点数据(state_{workstationId})
|
* @param stateList
|
*/
|
void saveDeviceStates(List<DeviceState> stateList) {
|
//employees.stream().collect(Collectors.groupingBy(Employee::getCity)
|
Map<Long,List<DeviceState>> maps = stateList.stream().collect(Collectors.groupingBy(DeviceState::getWorkstationId));
|
List<Long> workstationIds = stateList.stream().map(DeviceState::getWorkstationId).distinct().collect(Collectors.toList());
|
String deviceId;
|
for(Long wid : workstationIds) {
|
//创建时间序列
|
deviceId = IOTDBConstant.DB_PREFIX+"state_"+wid;
|
iotDBCommonService.setTemmplateIfNotSet(IOTDBConstant.TEMPLATE_STATE, deviceId);
|
|
}
|
|
List<MeasurementSchema> schemas = new ArrayList<>();
|
|
schemas.add(new MeasurementSchema("workstation_id", TSDataType.INT64));
|
schemas.add(new MeasurementSchema("value_collect", TSDataType.INT32));
|
|
schemas.add(new MeasurementSchema("calendar_code", TSDataType.TEXT));
|
schemas.add(new MeasurementSchema("factory_year", TSDataType.INT32));
|
schemas.add(new MeasurementSchema("factory_month", TSDataType.INT32));
|
schemas.add(new MeasurementSchema("factory_week", TSDataType.INT32));
|
schemas.add(new MeasurementSchema("factory_date", TSDataType.INT32));
|
schemas.add(new MeasurementSchema("shift_index", TSDataType.INT32));
|
schemas.add(new MeasurementSchema("shift_time_type", TSDataType.INT32));
|
schemas.add(new MeasurementSchema("wcs", TSDataType.INT32));
|
schemas.add(new MeasurementSchema("rps", TSDataType.INT32));
|
schemas.add(new MeasurementSchema("is_fix_point", TSDataType.BOOLEAN));
|
schemas.add(new MeasurementSchema("is_sync", TSDataType.BOOLEAN));
|
schemas.add(new MeasurementSchema("is_plan", TSDataType.INT32));//TODO 这个属性应该是GlobalWcsOfRps中的值,如何填写?
|
schemas.add(new MeasurementSchema("feedback_point_type", TSDataType.INT32));
|
schemas.add(new MeasurementSchema("feedback_id", TSDataType.INT64));
|
schemas.add(new MeasurementSchema("is_deleted", TSDataType.BOOLEAN));
|
schemas.add(new MeasurementSchema("employee_id", TSDataType.INT64));
|
|
|
|
Long wid;
|
List<DeviceState> states;
|
for(Entry<Long, List<DeviceState>> entry: maps.entrySet()) {
|
wid = entry.getKey();
|
|
deviceId = IOTDBConstant.DB_PREFIX+"state_"+wid;
|
Tablet tablet = new Tablet(deviceId, schemas);
|
|
states = entry.getValue();
|
tablet.rowSize = states.size();
|
DeviceState state;
|
for(int i=0;i<states.size();i++) {
|
state = states.get(i);
|
tablet.addTimestamp(i, state.getTime());
|
tablet.addValue("workstation_id", i, state.getWorkstationId());
|
tablet.addValue("value_collect", i, state.getValueCollect());
|
|
tablet.addValue("calendar_code", i, state.getCalendarCode());
|
tablet.addValue("factory_year", i, state.getFactoryYear());
|
tablet.addValue("factory_month", i, state.getFactoryMonth());
|
tablet.addValue("factory_week", i, state.getFactoryWeek());
|
tablet.addValue("factory_date", i, state.getFactoryDate());
|
tablet.addValue("shift_index", i, state.getShiftIndex());
|
tablet.addValue("shift_time_type", i, state.getShiftTimeType());
|
tablet.addValue("wcs", i, state.getWcs());
|
tablet.addValue("rps", i, state.getRps());
|
tablet.addValue("is_fix_point", i, state.getIsFixPoint());
|
tablet.addValue("is_sync", i, state.getIsSync());
|
tablet.addValue("is_plan", i, state.getIsPlan()==null ? -1 : state.getIsPlan());
|
tablet.addValue("feedback_point_type", i, state.getFeedbackPointType());
|
tablet.addValue("feedback_id", i, state.getFeedbackId() == null?0:state.getFeedbackId());
|
tablet.addValue("is_deleted", i, state.getIsDeleted());
|
tablet.addValue("employee_id", i, state.getEmployeeId() == null?0:state.getEmployeeId());
|
|
}
|
try {
|
this.iotdbConfig.getSessionPool().insertAlignedTablet(tablet);
|
} catch (Exception e) {
|
log.error("保存state固定点数据异常",e);
|
}
|
|
}
|
|
}
|
private List<DeviceState> getDefaultShift24HourPointDTOS(Long workStationId, String calendarCode, CalendarShiftInfoDTO shift) {
|
List<DeviceState> default24HourPointDTO = new ArrayList<>();
|
String factoryDate = shift.getFactoryDate();
|
String[] split = Func.split(factoryDate, "-");
|
int year = Integer.parseInt(split[0]);
|
int month = Integer.parseInt(split[1]);
|
int day = Integer.parseInt(split[2]);
|
for (int i = 1; i < 24; i++) {
|
LocalDateTime time = LocalDateTime.of(year, month, day, i, 0, 0);
|
//WorkstationState state = WorkstationStateConvert.INSTANCE.convert(shift);
|
|
DeviceState state = new DeviceState();
|
state.setIsSync(false);
|
state.setIsFixPoint(true);
|
state.setValueCollect(0);
|
state.setRps(0);
|
state.setWcs(0);
|
state.setWorkstationId(workStationId);
|
state.setTime(Long.valueOf(time.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()));
|
state.setCalendarCode(calendarCode);
|
|
state.setFeedbackPointType(FeedbackTimePointEnum.NO_FEED_BACK_POINT.getValue());
|
|
state.setFactoryDate(Integer.valueOf(String.join("", Func.split(shift.getFactoryDate(), "-"))));
|
state.setFactoryYear(shift.getFactoryYear());
|
state.setFactoryMonth(shift.getFactoryMonth());
|
state.setFactoryWeek(shift.getFactoryWeek());
|
state.setShiftIndex(shift.getShiftIndex());
|
state.setShiftTimeType(shift.getShiftTimeType());
|
|
state.setIsDeleted(Boolean.FALSE);
|
default24HourPointDTO.add(state);
|
}
|
return default24HourPointDTO;
|
}
|
|
/**
|
* 生成非默认的24小时固定点位
|
* @param worksationId 工位id
|
* @param calendarCode
|
* @param dateTime 固定点生成的日期
|
* @return
|
*/
|
private List<DeviceState> getNoDefaultShift24HourPointDTOS(Long worksationId, String calendarCode, DateTime dateTime) {
|
List<DeviceState> default24HourPointDTOList = new ArrayList<>();
|
CalendarMapper calendarMapper = (CalendarMapper) SpringUtil.getBean(CalendarMapper.class);
|
try {
|
List<CalendarShiftInfoDTO> calendarShiftList = calendarMapper.getCalendarShiftInfoToday(calendarCode, DateUtil.formatDate(dateTime));
|
for (int i = 0; i < 24; i++) {
|
LocalDateTime time = LocalDateTime.of(dateTime.year(), dateTime.month() + 1, dateTime.dayOfMonth(), i, 0, 0);//每小时0分0秒
|
DeviceState state = new DeviceState();
|
state.setIsSync(false);
|
state.setIsFixPoint(true);
|
state.setValueCollect(0);
|
state.setRps(0);
|
state.setWcs(0);
|
state.setWorkstationId(worksationId);
|
state.setTime(Long.valueOf(time.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()));
|
state.setCalendarCode(calendarCode);
|
state.setFeedbackPointType(FeedbackTimePointEnum.NO_FEED_BACK_POINT.getValue());
|
state.setIsDeleted(false);
|
|
//如果state.ts在calendarShiftList区间内,则填充班制和生产日历信息,并将state加入到default24HourPointDTO中
|
packCalendarShiftInfoForTimePoint(calendarShiftList, default24HourPointDTOList, state);
|
}
|
} catch (Exception e) {
|
log.error("生成固定点数据异常",e);
|
}
|
return default24HourPointDTOList;
|
}
|
|
private void packCalendarShiftInfoForTimePoint(List<CalendarShiftInfoDTO> calendarShiftList, List<DeviceState> default24HourPointDTOList, DeviceState state) {
|
if (Func.isNotEmpty(calendarShiftList)) {
|
CalendarShiftInfoDTO relatedShift = calendarShiftList.stream().filter(item -> {
|
return item.getStartTime().getTime() <= state.getTime().longValue() && item.getEndTime().getTime() > state.getTime().longValue();
|
}).findFirst().orElse(null);
|
|
if (Func.isNotEmpty(relatedShift)) {
|
state.setShiftIndex(relatedShift.getShiftIndex());
|
state.setShiftTimeType(relatedShift.getShiftTimeType());
|
state.setFactoryYear(relatedShift.getFactoryYear());
|
state.setFactoryMonth(relatedShift.getFactoryMonth());
|
state.setFactoryWeek(relatedShift.getFactoryWeek());
|
String factoryDate = relatedShift.getFactoryDate();
|
String[] split = Func.split(factoryDate, "-");
|
state.setFactoryDate(Integer.valueOf(String.join("", split)));
|
state.setIsDeleted(Boolean.FALSE);
|
default24HourPointDTOList.add(state);
|
return;
|
}
|
log.warn("工位{} 日历{} 未找到整点班次信息", state.getWorkstationId(), state.getCalendarCode());
|
return;
|
}
|
log.error("工位{} 日历{} 无自然天{}班次信息", new Object[]{state.getWorkstationId(), state.getCalendarCode(), state.getTime()});
|
}
|
|
//不一定能用上
|
private void buildDefaultFactoryDay(DateTime dateTime, DeviceState workstationState) {
|
if ("#default#".equals(workstationState.getCalendarCode()) && Func.isEmpty(workstationState.getFactoryMonth())) {
|
workstationState.setFactoryYear(Integer.valueOf(DateUtil.year(dateTime)));
|
workstationState.setFactoryWeek(LocalDateTimeUtils.getWeek(dateTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()));
|
workstationState.setFactoryMonth(Integer.valueOf(DateUtil.month(dateTime) + 1));
|
workstationState.setFactoryDate(Integer.valueOf(DatePattern.PURE_DATE_FORMAT.format(dateTime)));
|
workstationState.setTime(Long.valueOf(DateUtil.beginOfDay(dateTime).getTime()));
|
workstationState.setShiftIndex(CommonConstant.DEFAULT_SHIFT_INDEX);
|
workstationState.setShiftTimeType(CommonConstant.DEFAULT_SHIFT_TYPE);
|
workstationState.setFeedbackPointType(FeedbackTimePointEnum.NO_FEED_BACK_POINT.getValue());
|
workstationState.setIsDeleted(Boolean.FALSE);
|
}
|
}
|
}
|