pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/rtuUpgrage/RtuUpgradeStateReceiverCtrl.java
@@ -2,11 +2,23 @@
import com.dy.common.softUpgrade.state.UpgradeInfo;
import com.dy.common.softUpgrade.state.UpgradeRtu;
import com.dy.common.softUpgrade.state.UpgradeState;
import com.dy.common.util.Callback;
import com.dy.common.util.CreateRandom;
import com.dy.common.util.DateTime;
import com.dy.common.util.ThreadJob;
import com.dy.common.webUtil.BaseResponse;
import com.dy.pipIrrGlobal.pojoRm.UgRtuProgram;
import com.dy.pipIrrGlobal.pojoRm.UgRtuTask;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
 * @Author: liurunyu
@@ -18,22 +30,241 @@
@RestController
@RequestMapping(path = "rtuUpgradeStateReceiver")
public class RtuUpgradeStateReceiverCtrl {
    protected static UpgradeInfo cache ;
    @Autowired
    private RtuUpgradeSv sv ;
    /**
     * rtu远程升级任务通信中间件执行情况统计回收
     * @param vo 数据
     * @param info 数据
     * @return 操作结果
     */
    @Hidden //不公开接口,其只有通信中间件调用
    @PostMapping(path = "/receive")
    public BaseResponse<Boolean> receive(@RequestBody UpgradeInfo vo){
        log.info("接收到的RTU远程升级状态数据为:{}",vo.toString());
        if(vo.ugRtuStateList != null && vo.ugRtuStateList.size() > 0){
            if(vo.ugRtuStateList.size() < 10){
                for (UpgradeRtu upgradeRtu : vo.ugRtuStateList) {
                    log.info(upgradeRtu.toString());
    public BaseResponse<Boolean> receive(@RequestBody UpgradeInfo info){
        log.info("接收到的RTU远程升级状态数据为:{}", info.toString());
        //进行排序
        //Comparator<UpgradeRtu> comparator = Comparator.comparing(UpgradeRtu::getRtuAddr, Comparator.naturalOrder());
        //info.ugRtuStateList = info.ugRtuStateList.stream().sorted(comparator).collect(Collectors.toList());
        if(info.ugRtuStateList != null && info.ugRtuStateList.size() > 0){
            if(info.ugRtuStateList.size() < 10){
                for (UpgradeRtu rtuVo : info.ugRtuStateList) {
                    log.info(rtuVo.toString());
                }
            }
        }
        if(cache == null){
            //此时不做任务操作,只保障cache不为空, 等待下次发来数据
            if(info.ugRtuStateList != null && info.ugRtuStateList.size() > 0){
                List<UpgradeRtu> overList = info.ugRtuStateList.stream().filter(itemVo -> itemVo.isOver).collect(Collectors.toList()) ;
                if(overList != null && overList.size() > 0){
                    cache = info;
                    this.save2Db(info.ugTaskId, overList);
                }
            }
        }else{
            //当cache中有值时,进行比对存储,对比目的是防止重复操作数据库
            if(info.ugRtuStateList != null && info.ugRtuStateList.size() > 0){
                //此时保证两个集合都不为null
                this.save2Db(info.ugTaskId, info.ugRtuStateList, cache.ugRtuStateList);
                cache = info;
            }
        }
        return null;
    }
    /**
     * 比对并数据库存储
     * @param taskId
     * @param list
     */
    private void save2Db(String taskId, List<UpgradeRtu> list){
        list.stream().forEach(vo -> {
            if(vo != null) {
                this.sv.saveRtuUpgradeState(Long.parseLong(taskId), vo);
            }
        });
    }
    /**
     * 比对并数据库存储
     * @param newList
     * @param oldList
     */
    private void save2Db(String taskId, List<UpgradeRtu> newList, List<UpgradeRtu> oldList){
        List<UpgradeRtu> newOverList = newList.stream().filter(vo -> vo.isOver).collect(Collectors.toList()) ;
        for(UpgradeRtu nvo : newOverList){
            if(nvo != null) {
                if(oldList.stream().anyMatch(vo -> vo.rtuAddr.equals(nvo.rtuAddr) && vo.isOver == false)){
                    //上次没有升级结束,而当前升级结束了
                    this.sv.saveRtuUpgradeState(Long.parseLong(taskId), nvo);
                }
            }
        }
    }
    /////////////////////////////////////////////////////
    //
    // 以下模拟数据
    //
    /////////////////////////////////////////////////////
    private static ThreadJob threadJob ;
    protected void demo(){
        if(cache == null){
            UgRtuTask tpo = this.sv.selectLastTask() ;
            if(tpo != null) {
                UgRtuProgram ppo = this.sv.selectProgramById(tpo.programId);
                if (ppo == null) {
                    List<String> taskRtuAddrs = this.sv.selectAllRtuAddrByTask("" + tpo.id);
                    if (taskRtuAddrs != null && taskRtuAddrs.size() > 0) {
                        cache = new UpgradeInfo();
                        cache.ugTaskId = "" + tpo.id;
                        cache.ugOverallState = new UpgradeState() ;
                        cache.ugOverallState.rtuTotal = taskRtuAddrs.size() ;
                        cache.ugRtuStateList = new ArrayList<>() ;
                        for (String addr : taskRtuAddrs) {
                            UpgradeRtu rtu = new UpgradeRtu() ;
                            rtu.rtuAddr = addr ;
                            rtu.state = UpgradeRtu.STATE_UNSTART ;
                            rtu.totalPackage = (ppo.programBytes.length / 512) + ((ppo.programBytes.length % 512)>0?1:0) ;
                            rtu.isOver = false ;
                            cache.ugRtuStateList.add(rtu) ;
                        }
                        if(threadJob == null){
                            threadJob = new ThreadJob() {
                                @Override
                                public Object execute() throws Exception {
                                    runDemo() ;
                                    return null;
                                }
                            };
                            try{
                                threadJob.start(new Callback() {
                                    @Override
                                    public void call(Object obj) {
                                    }
                                    @Override
                                    public void call(Object... objs) {
                                    }
                                    @Override
                                    public void exception(Exception e) {
                                    }
                                });
                            }catch (Exception e){
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
    }
    private void runDemo(){
        boolean hasRunning = true ;
        while (true){
            for(UpgradeRtu rtu : cache.ugRtuStateList){
                this.rtuUpgrade(rtu) ;
                hasRunning = this.statisticsNowUpgradeState() ;
                if(!hasRunning){
                    break ;
                }
            }
            if(!hasRunning){
                break ;
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    private void rtuUpgrade(UpgradeRtu rtu){
        if(rtu.lastDownDt == null){
            //第一次
            this.dealUpgradeFirstTime(rtu);
        }else{
            this.dealUpgrade(rtu);
        }
    }
    private void dealUpgradeFirstTime(UpgradeRtu rtu){
        int n = Integer.parseInt(new CreateRandom().create(1)) ;
        if(n == 0){
            rtu.state = UpgradeRtu.STATE_OFFLINE ;
            rtu.currentPackage = 0 ;
            rtu.currentRamAddr = 0x00 ;
            rtu.lastDownDt = "" ;
            rtu.reTryTimes = 0 ;
            rtu.isOver = false ;
        }else{
            rtu.state = UpgradeRtu.STATE_RUNNING ;
            rtu.currentPackage = 1 ;
            rtu.currentRamAddr = 0x00 ;
            rtu.lastDownDt = DateTime.yyyy_MM_dd_HH_mm_ss() ;
            rtu.reTryTimes = 0 ;
            rtu.isOver = false ;
        }
    }
    private void dealUpgrade(UpgradeRtu rtu){
        if(rtu.state == UpgradeRtu.STATE_OFFLINE){
            //离线的,不处理
            return ;
        }
        int n = Integer.parseInt(new CreateRandom().create(2)) ;
        if(n == 44 || n == 45 || n == 54){
            if(rtu.currentPackage == 1){
                //1包死
                rtu.state = UpgradeRtu.STATE_FAILONE ;
                return ;
            }
        }
        if(rtu.currentPackage == rtu.totalPackage){
            //升级结束
            rtu.state = UpgradeRtu.STATE_SUCCESS ;
            rtu.isOver = true ;
            return ;
        }
        rtu.state = UpgradeRtu.STATE_RUNNING ;
        rtu.currentPackage += 1 ;
        rtu.currentRamAddr = 0x00 + UpgradeRtu.RAMADDRADD ;
        rtu.lastDownDt = DateTime.yyyy_MM_dd_HH_mm_ss() ;
        rtu.reTryTimes = 0 ;
        rtu.isOver = false ;
    }
    /**
     * 当前升级状态
     * @return
     */
    public boolean statisticsNowUpgradeState() {
        boolean hasRunning = false ;
        if(cache.ugRtuStateList != null && cache.ugRtuStateList.size() > 0){
            for(UpgradeRtu rtu : cache.ugRtuStateList){
                if(rtu.state == UpgradeRtu.STATE_OFFLINE){
                    cache.ugOverallState.offLineTotal ++ ;
                }else if(rtu.state == UpgradeRtu.STATE_UNSTART){
                    cache.ugOverallState.unStartTotal ++ ;
                }else if(rtu.state == UpgradeRtu.STATE_RUNNING){
                    cache.ugOverallState.runningTotal ++ ;
                    hasRunning = true ;
                }else if(rtu.state == UpgradeRtu.STATE_SUCCESS) {
                    cache.ugOverallState.successTotal++;
                }else if(rtu.state == UpgradeRtu.STATE_FAILONE) {
                    cache.ugOverallState.failOneTotal++;
                    cache.ugOverallState.failTotal++;
                }else if(rtu.state == UpgradeRtu.STATE_FAIL) {
                    cache.ugOverallState.failTotal++;
                }
                if(rtu.isOver){
                    cache.ugOverallState.overTotal++;
                }
            }
        }
        return hasRunning ;
    }
}