yangys
2025-11-24 11d4be720620abf502d35000e2ed40d30c4023bf
collect/src/main/java/com/qianwen/mdc/collect/service/DeviceOfflineCheckService.java
@@ -1,10 +1,22 @@
package com.qianwen.mdc.collect.service;
import java.util.Arrays;
import java.util.Date;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Sets;
import com.qianwen.mdc.collect.cache.TimeSliceCache;
import com.qianwen.mdc.collect.constants.CommonConstant;
import com.qianwen.mdc.collect.dto.CacheBuildDTO;
import com.qianwen.mdc.collect.dto.CalendarShiftTimeSlicesDTO;
import com.qianwen.mdc.collect.mapper.iotdb.DeviceStateMapper;
import com.qianwen.mdc.collect.utils.LocalDateTimeUtils;
import com.xxl.job.core.log.XxlJobLogger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -15,9 +27,7 @@
import com.qianwen.mdc.collect.dto.WorkstationDTO;
import com.qianwen.mdc.collect.entity.iotdb.DeviceState;
import com.qianwen.mdc.collect.entity.iotdb.ProcessParam;
import com.qianwen.mdc.collect.enums.FeedbackTimePointEnum;
import com.qianwen.mdc.collect.mapper.iotdb.ProcessParamMapper;
import com.qianwen.mdc.collect.vo.FactoryDataVO;
import cn.hutool.core.util.ObjectUtil;
/**
@@ -41,10 +51,13 @@
    private ProcessParamMapper processParamMapper;
    
    @Autowired
   private FactoryDataService factoryDataService;
   private DeviceStateService deviceStateService;
    @Autowired
    private TimeSliceCache timeSliceCache;
    @Autowired
    private DeviceStateMapper deviceStateMapper;
    /**
     * 保存状态固定点数据(state_{workstationId})
     * @param workstationIdList
     */
    public void checkOffline() {
       //将数据按照工位id分组
@@ -67,34 +80,109 @@
    }
    /**
     * 检查一个工位是否离线,离线则填充离线状态数据
     * @param workstationId
     * @param workstationId 工位id
     */
    public void handleWorkstationOffline(long workstationId) {
       ProcessParam lastParam = processParamMapper.lastParamByWorstationId(workstationId);
       long nowMills = System.currentTimeMillis();
       long onlineRange = nowMills - offlineConfigDuration;
        long nowMills = System.currentTimeMillis();
        long lastOnlineTime = nowMills - offlineConfigDuration;
        /*
       ProcessParam lastParam = processParamMapper.lastParamByWorkstationId(workstationId);
       if(lastParam != null && lastParam.getTime()> onlineRange) {
          //有数据,且在判定时间内-》在线
          return;
       }
       }*/
        DeviceState lastState = deviceStateMapper.lastNoFixedState(workstationId);
        if(lastState != null && lastState.getTime() > lastOnlineTime) {
            //有数据,且在判定时间内-》在线
            return;
        }
       //TODO 这里一直离线是什么数据
        XxlJobLogger.log("离线"+workstationId);
       //时间段内无参数,说明设备没采集数据判定为离线,插入状态,然后发送realTime消息给mdc
        //作为实时数据发送
       ProcessParam statusParam = new ProcessParam();
       statusParam.setTime(nowMills);
       statusParam.setN("DeviceStatus");
       statusParam.setV(OFFLINE_VALUE);
       statusParam.setWorkstationId(workstationId);
       if(lastParam == null || !lastParam.getN().equals("DeviceStatus")) {
       //if(lastState == null || !lastParam.getN().equals("DeviceStatus")) {
        if(lastState == null || lastState.getTime() <= lastOnlineTime) {
          //之前无任何采集的数据(或者上一条不是状态数据),新加一条离线状态数据
          paramService.insertProcessParam(statusParam);
          //paramService.insertProcessParam(statusParam);
          //插入状态表
          DeviceState offLineState = new DeviceState();
            offLineState.setTime(nowMills);
            String calendarCode = workstationCache.getWorkstationCalendarCodeForDate(workstationId, DateUtil.formatDate(DateUtil.date(nowMills)));
            offLineState.setCalendarCode(calendarCode);//111
            this.fillCalendar(offLineState);
            offLineState.setValueCollect(Integer.parseInt(OFFLINE_VALUE));
            offLineState.setWcs(offLineState.getValueCollect());
            offLineState.setWorkstationId(workstationId);
            offLineState.setIsFixPoint(false);
            offLineState.setIsDeleted(false);
            offLineState.setIsSync(false);
          deviceStateService.saveDeviceStates(Collections.singletonList(offLineState));
            XxlJobLogger.log("保存离线状态"+workstationId);
       }
       
       //通知mdc更新实时状态
       paramService.sendRealtimeDataMsg(statusParam);
       
    }
    /**
     * 填充数据日历
     * @param state 状态对象
     */
    void fillCalendar(DeviceState state){
        if (ObjectUtil.isEmpty(state.getCalendarCode())) {
            state.setCalendarCode(CommonConstant.DEFAULT_CODE);
        }
        java.util.Date collectTime = new java.util.Date(state.getTime());
        boolean isDefaultCalendar = true;
        if (!CommonConstant.DEFAULT_CODE.equals(state.getCalendarCode())) {
            CalendarShiftTimeSlicesDTO calendarShiftTimeSlicesDTO = timeSliceCache.getTimeSliceShift(state.getCalendarCode(), collectTime);//从redis中获得日历的时间切片
            if (ObjectUtil.isEmpty(calendarShiftTimeSlicesDTO)) {
                LocalDate targetDate = Instant.ofEpochMilli(state.getTime()).atZone(ZoneOffset.systemDefault()).toLocalDate();
                CacheBuildDTO cacheBuildDTO = CacheBuildDTO.builder().tenantIds(Sets.newHashSet(new String[]{"000000"})).calendarCode(state.getCalendarCode()).targetDate(targetDate).build();
                timeSliceCache.build(cacheBuildDTO);
                calendarShiftTimeSlicesDTO = timeSliceCache.getTimeSliceShift(state.getCalendarCode(), collectTime);
            }
            if (ObjectUtil.isNotEmpty(calendarShiftTimeSlicesDTO)) {
                state.setShiftIndex(calendarShiftTimeSlicesDTO.getShiftIndex());
                state.setShiftTimeType(Integer.valueOf(calendarShiftTimeSlicesDTO.getShiftTimeType()));
                state.setFactoryDate(Integer.valueOf(calendarShiftTimeSlicesDTO.getFactoryDate().replaceAll("-", "")));
                state.setFactoryWeek(calendarShiftTimeSlicesDTO.getFactoryWeek());
                state.setFactoryMonth(calendarShiftTimeSlicesDTO.getFactoryMonth());
                state.setFactoryYear(calendarShiftTimeSlicesDTO.getFactoryYear());
                isDefaultCalendar = false;
            }
        }
        //无日历切片,使用采集时间填充factoryYear,month,date,week几个属性
        if (isDefaultCalendar) {
            log.info("离线检查无日历切片");
            LocalDate localDate = Instant.ofEpochMilli(state.getTime()).atZone(ZoneOffset.systemDefault()).toLocalDate();
            state.setFactoryDate(Integer.valueOf(DatePattern.PURE_DATE_FORMAT.format(collectTime)));
            state.setFactoryYear(DateUtil.year(collectTime));
            state.setFactoryWeek(LocalDateTimeUtils.getWeek(localDate));
            state.setFactoryMonth(DateUtil.month(collectTime) + 1);
            state.setShiftIndex(CommonConstant.DEFAULT_SHIFT_INDEX);
            state.setShiftTimeType(CommonConstant.DEFAULT_SHIFT_TYPE);
        }
    }
    
}