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 includeWorkstationIds) { List result; Map workStations = workstationCache.getWorkstations(); if (ObjectUtil.isEmpty(workStations)) { return; } Collection values = workStations.values(); if (ObjectUtil.isNotEmpty(includeWorkstationIds)) { values = values.stream().filter(item -> includeWorkstationIds.contains(item.getId().toString())).collect(Collectors.toList()); } List calendarCodeList = workStations.values().stream().map(WorkstationDTO::getCalendarCode).distinct().filter(Func::isNotEmpty).collect(Collectors.toList()); Map> shiftMap ; String formatDateTime = DateUtil.formatDate(dateTime); if (Func.isNotEmpty(calendarCodeList)) { List calendarShiftInfoDTOList = calendarMapper.getCalendarShiftInfo(calendarCodeList, DateUtil.year(dateTime), formatDateTime); shiftMap = calendarShiftInfoDTOList.stream().collect(Collectors.groupingBy(CalendarShiftInfoDTO::getCode)); }else { shiftMap = Collections.emptyMap(); } List res = Lists.newArrayList(); for (WorkstationDTO workstationDTO : values) { result = Lists.newArrayList(); List 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> 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 stateList) { //employees.stream().collect(Collectors.groupingBy(Employee::getCity) Map> maps = stateList.stream().collect(Collectors.groupingBy(DeviceState::getWorkstationId)); List 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 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 states; for(Entry> 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 getDefaultShift24HourPointDTOS(Long workStationId, String calendarCode, CalendarShiftInfoDTO shift) { List 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 getNoDefaultShift24HourPointDTOS(Long worksationId, String calendarCode, DateTime dateTime) { List default24HourPointDTOList = new ArrayList<>(); CalendarMapper calendarMapper = (CalendarMapper) SpringUtil.getBean(CalendarMapper.class); try { List 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 calendarShiftList, List 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); } } }