package com.shkj.wms.plc;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.shkj.common.constant.HttpStatus;
import com.shkj.common.constant.RedisConstant;
import com.shkj.common.core.domain.Result;
import com.shkj.common.core.domain.entity.BaseConsignor;
import com.shkj.common.utils.DateUtils;
import com.shkj.plc.sdk.device.PLCReadAndWrite;
import com.shkj.plc.sdk.device.PLCUtil;
import com.shkj.plc.sdk.device.PlcOperate;
import com.shkj.system.service.ISysParameterService;
import com.shkj.wms.bo.*;
import com.shkj.wms.domain.*;
import com.shkj.wms.scheduled.ScheduledTasks;
import com.shkj.wms.service.*;
import com.shkj.wms.third.rcs.RCSUtil;
import com.shkj.wms.third.rcs.enums.RCSTaskTypeEnum;
import com.shkj.wms.utils.TunnelTaskUtil;
import com.shkj.wms.vo.*;
import com.shkj.wms.constants.ParameterConstants;
import com.shkj.wms.enums.PlcPropertyEnum;
import com.shkj.wms.enums.TaskStatusEnum;
import com.shkj.wms.enums.TaskTypeEnum;
import com.shkj.wms.mapper.BaseLocationPlcMapper;
import com.shkj.wms.mapper.BasePointDeviceMapper;
import com.shkj.wms.mapper.BusinDpsContainerRecordMapper;
import com.shkj.wms.service.IBaseGoodsDataService;
import com.shkj.wms.service.IBusinDataTaskService;
import com.shkj.wms.service.IPutInOutStorageService;
import com.shkj.wms.utils.JsonUtil;
import com.sun.xml.internal.bind.v2.TODO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@Component("PlcEventTask")
@Slf4j
@EnableScheduling
public class PlcEventTask {

    @Autowired
    IWcsPlcConnectService iWcsPlcConnectService;

    @Resource
    RedisTemplate redisTemplate;

    @Autowired
    RCSUtil rcsUtil;

    @Autowired
    IWcsPlcPropertyService iWcsPlcPropertyService;

    @Autowired
    IBusinDataTaskService iBusinDataTaskService;

    @Resource
    IBusinDataTaskDetailService iBusinDataTaskDetailService;

    @Autowired
    IPutInOutStorageService iPutInOutStorageService;

    @Autowired
    IBaseGoodsDataService iBaseGoodsDataService;

    @Autowired
    IBasePointService iBasePointService;

    @Autowired
    IBasePunchRecordService iBasePunchRecordService;

    @Autowired
    ISysParameterService isysParameterService;

    @Resource
    BaseLocationPlcMapper baseLocationPlcMapper;

    @Autowired
    IBaseContainerService iBaseContainerService;

    @Autowired
    IBaseLocationService iBaseLocationService;

    @Autowired
    private ISysParameterService sysParameterService;

    @Resource
    private TunnelTaskUtil tunnelTaskUtil;

    @Resource
    BusinDpsContainerRecordMapper businDpsContainerRecordMapper;

    @Resource
    IBusinEnptyContainerService iBusinEnptyContainerService;

    @Resource
    IBusinPickupService iBusinPickupService;

    @Value("${plc.firstBarcode}")
    private String firstBarAddress;

    @Value("${plc.secondBarcode}")
    private String secondBarAddress;

    @Value("${plc.thirdBarcode}")
    private String thirdBarAddress;

    @Value("${plc.containerCode}")
    private String containerCodeAddress;

    @Resource
    private BasePointDeviceMapper basePointDeviceMapper;

    @Resource
    private PlcInit plcInit;

    @Resource
    private ScheduledTasks scheduledTasks;

    private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(8);

    // @Scheduled(fixedRate = 200)
    public void init() {
        //查询需要连接的PLC,初始化连接对象
        List<WcsPlcConnectVo> plcList = iWcsPlcConnectService.selectWcsPlcConnectList(new WcsPlcConnect().setIsActive("1"));
        if (plcList.size() == 0) {
            return;
        }
        for (WcsPlcConnectVo conn : plcList) {
            if ("1".equals(conn.getDevType())) {
                if (conn.getPlcIp().contains(".60")) {
                    PlcOperate plcOperate_60 = plcInit.getPlcOperate_60();
                    if (plcOperate_60 == null) {
                        plcInit.connect(conn.getPlcIp());
                    }
                    plcTask(plcOperate_60, conn, conn.getPointTables());
                    doDevStatus(plcOperate_60, "1");
                }

                if (conn.getPlcIp().contains(".70")) {
                    PlcOperate plcOperate_70 = plcInit.getPlcOperate_70();
                    if (plcOperate_70 == null) {
                        plcInit.connect(conn.getPlcIp());
                    }
                    plcTask(plcOperate_70, conn, conn.getPointTables());
                    doDevStatus(plcOperate_70, "2");
                }

                if (conn.getPlcIp().contains(".80")) {
                    PlcOperate plcOperate_80 = plcInit.getPlcOperate_80();
                    if (plcOperate_80 == null) {
                        plcInit.connect(conn.getPlcIp());
                    }
                    plcTask(plcOperate_80, conn, conn.getPointTables());
                    doDevStatus(plcOperate_80, "3");
                }

                if (conn.getPlcIp().contains(".90")) {
                    PlcOperate plcOperate_90 = plcInit.getPlcOperate_90();
                    if (plcOperate_90 == null) {
                        plcInit.connect(conn.getPlcIp());
                    }
                    plcTask(plcOperate_90, conn, conn.getPointTables());
                    doDevStatus(plcOperate_90, "4");
                }

                if (conn.getPlcIp().contains(".100")) {
                    PlcOperate plcOperate_100 = plcInit.getPlcOperate_100();
                    if (plcOperate_100 == null) {
                        plcInit.connect(conn.getPlcIp());
                    }
                    plcTask(plcOperate_100, conn, conn.getPointTables());
                    doDevStatus(plcOperate_100, "5");
                }

                if (conn.getPlcIp().contains(".110")) {
                    PlcOperate plcOperate_110 = plcInit.getPlcOperate_110();
                    if (plcOperate_110 == null) {
                        plcInit.connect(conn.getPlcIp());
                    }
                    plcTask(plcOperate_110, conn, conn.getPointTables());
                    doDevStatus(plcOperate_110, "6");
                }
            }
//            if(conn.getPlcIp().contains(".41")){
//                PlcOperate plcOperate_41 = plcInit.getPlcOperate_41();
//                if (plcOperate_41 ==null){
//                    plcInit.connect(conn.getPlcIp());
//                }
//                plcTask(plcInit.getPlcOperate_41(), conn, conn.getPointTables());
//            }
//
//            if(conn.getPlcIp().contains(".50")){
//                PlcOperate plcOperate_50 = plcInit.getPlcOperate_50();
//                if (plcOperate_50 ==null){
//                    plcInit.connect(conn.getPlcIp());
//                }
//                plcTask(plcOperate_50, conn, conn.getPointTables());
//            }


        }
    }

    // @Scheduled(fixedRate = 200)
    public void init1() {
        //查询需要连接的PLC,初始化连接对象
        List<WcsPlcConnectVo> plcList = iWcsPlcConnectService.selectWcsPlcConnectList(new WcsPlcConnect().setIsActive("1"));
        if (plcList.size() == 0) {
            return;
        }
        for (WcsPlcConnectVo conn : plcList) {
            if ("2".equals(conn.getDevType()) && conn.getPlcIp().contains(".41")) {
                PlcOperate plcOperate_41 = plcInit.getPlcOperate_41();
                if (plcOperate_41 == null) {
                    plcInit.connect(conn.getPlcIp());
                }
                plcTask(plcInit.getPlcOperate_41(), conn, conn.getPointTables());
            }
        }
    }

    // @Scheduled(fixedRate = 200)
    public void init2() {
        //查询需要连接的PLC,初始化连接对象
        List<WcsPlcConnectVo> plcList = iWcsPlcConnectService.selectWcsPlcConnectList(new WcsPlcConnect().setIsActive("1"));
        if (plcList.size() == 0) {
            return;
        }
        for (WcsPlcConnectVo conn : plcList) {
            if ("3".equals(conn.getDevType()) && conn.getPlcIp().contains(".50")) {
                PlcOperate plcOperate_50 = plcInit.getPlcOperate_50();
                if (plcOperate_50 == null) {
                    plcInit.connect(conn.getPlcIp());
                }
                plcTask(plcOperate_50, conn, conn.getPointTables());
            }
        }
    }

    //  @Scheduled(fixedDelay = 6000)
    public void writePlcheartbeat() {
        //根据连接的plcId获取属性
        PlcOperate plcOperate = plcInit.getPlcOperate_41();
        PLCReadAndWrite plcReadAndWrite = new PLCReadAndWrite();
        Map<String, Object> readPointMap = new HashMap<>();
        String heartbeat = "DB320.2.0";
        readPointMap.put(heartbeat, "Boolean");
        Map<String, Object> pointMap = plcReadAndWrite.readPlcData(plcOperate, JsonUtil.toJSONString(readPointMap));

        //读取心跳，并判断是写入true还是false;
        Boolean heartbeatV = false;

        if (pointMap.containsKey(heartbeat)) {
            heartbeatV = Boolean.valueOf(pointMap.get(heartbeat).toString());
        }
        heartbeatV = (heartbeatV == true) ? false : true;
        Map<String, Object> writeHbMap = new HashMap<>(1);
        writeHbMap.put("Boolean", heartbeatV);
        Map<String, Object> allHbMap = new HashMap<>(1);
        allHbMap.put(heartbeat, writeHbMap);
        Boolean heartType = plcReadAndWrite.execWrite(plcOperate, JsonUtil.toJSONString(allHbMap));
        if (!heartType) {
            log.info("心跳写入失败，重连服务器");
            plcInit.connect(null);
        }
    }


    public void plcTask(PlcOperate plcOperate, WcsPlcConnectVo conn, String pointTables) {
        LocalTime start = LocalTime.now();
        try {
            Result<BaseConsignor> result = iBaseGoodsDataService.getErpConsignorId();
            if (!Result.isOk(result)) {
                log.info(result.getMsg());
            }
            //获取仓库ID
            BaseConsignor baseConsignor = result.getData();
            Long branchId = baseConsignor.getBranchId();

            Long plcId = conn.getId();
            //根据连接的plcId获取属性
            PLCReadAndWrite plcReadAndWrite = new PLCReadAndWrite();
            Map<String, Object> pointMap = plcReadAndWrite.readPlcData(plcOperate, pointTables);
            //读取数据失败时，进行重连
            if (ObjectUtils.isEmpty(pointMap)) {
                plcInit.connect(conn.getPlcIp());
                return;
            }


            List<WcsPlcProperty> propertyList = iWcsPlcPropertyService.getWcsPlcPropertyByPlcId(plcId);
            //任务ID
            Long taskId = 0L;
            // 设备类型：2（机械手输送线）3（立库输送线）1（堆垛机）
            switch (conn.getDevType()) {
                //机械手区域输送线保险杠到达请求，处理业务逻辑入库及呼叫AGV
                case "2":
                    String readAddress = "";
                    String writeTaskId = "";
                    String valueType = "";

                    String heartbeat = "";
                    String hbValueType = "";
                    String autoAddress = "";

                    String writeopen = "";
                    String writeopenType = "";
                    String writopenRelPoint = "";

                    String startPointno = isysParameterService.selectConfigByKey(branchId, ParameterConstants.ParameterSystem.putout_point);
                    BasePointDeviceQueryBo pointQueryBoup = new BasePointDeviceQueryBo();
                    pointQueryBoup.setGroupNo(startPointno);

                    BasePointDeviceVo pointDevice = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBoup);
                    String startPoint = pointDevice.getPointNo();

                    for (WcsPlcProperty wcsPlcProperty : propertyList) {
                        //产品到达出入口请求AGV
                        if (wcsPlcProperty.getPointType().equals("5")) {
                            readAddress = wcsPlcProperty.getAddress();
                            //任务ID
                        } else if (wcsPlcProperty.getPointType().equals("6")) {
                            writeTaskId = wcsPlcProperty.getAddress();
                            valueType = wcsPlcProperty.getValueType();
                        } else if (wcsPlcProperty.getPointType().equals("9")) {
                            //心跳
                            heartbeat = wcsPlcProperty.getAddress();
                            hbValueType = wcsPlcProperty.getValueType();
                        } else if (wcsPlcProperty.getPointType().equals("10")) {
                            autoAddress = wcsPlcProperty.getAddress();
                        } else if (wcsPlcProperty.getPointType().equals("1")) {
                            //是否放行
                            writeopen = wcsPlcProperty.getAddress();
                            writeopenType = wcsPlcProperty.getValueType();
                            writopenRelPoint = wcsPlcProperty.getRelPoint();
                        }
                    }
                    if (redisTemplate.opsForValue().get("PLCAuto") == null) {
                        redisTemplate.opsForValue().set("PLCAuto", true);
                    }

                    redisTemplate.opsForValue().set("PLCAuto", true);


                    if (pointMap.containsKey(writeopen) && Boolean.valueOf(pointMap.get(writeopen).toString())) {
                        Map map = new HashMap();
                        map.put("posId", writopenRelPoint);
                        //rcsUtil.openRun(map);
                    }

                    // 电柜状态是否是自动，如果是自动则继续流程
                    if (ObjectUtils.isNotEmpty(pointMap) && Boolean.valueOf(pointMap.get(autoAddress).toString())) {
                        redisTemplate.opsForValue().set("PLCAuto", true);
                        if (pointMap.containsKey(readAddress) && Boolean.valueOf(pointMap.get(readAddress).toString())) {
                            //读取条码治具点位内容
                            String firstBarcode = pointMap.get(firstBarAddress).toString().trim();
                            String secondBarcode = pointMap.get(secondBarAddress).toString().trim();
                            String thirdBarcode = pointMap.get(thirdBarAddress).toString().trim();
                            String containerCode = pointMap.get(containerCodeAddress).toString().trim();
//                            containerCode=containerCode.substring(0,containerCode.length()-1);
                            log.info("治具编号" + containerCode + "first:" + firstBarcode + "second:" + secondBarcode + "third:" + thirdBarcode);
                            //连续读到相同治具编号时不生成新任务
                            String redisContainerCode = redisTemplate.opsForValue().get("autoTask").toString();
                            if (redisContainerCode.equals(containerCode)) {
                                return;
                            }

                            //任务编号
                            int plcTaskIdValue = Integer.valueOf(pointMap.get(writeTaskId).toString());
                            //任务编号为0时，可以执行
                            if (plcTaskIdValue == 0) {
                                //根据读取的治具条码，匹配治具ID
//                                Long containerId = (Long) redisTemplate.opsForValue().get(RedisConstant.redisContainer + containerCode);
                                //新增任务
                                MachineHandAddBo mhbo = new MachineHandAddBo();
                                mhbo.setFirstBarcode(firstBarcode);
                                mhbo.setSecondBarcode(secondBarcode);
                                mhbo.setThirdBarcode(thirdBarcode);
                                BaseContainer one = new BaseContainer();
                                if (containerCode.equals("ERROR")) {
                                    one.setId(0L);
                                } else {
                                    one = iBaseContainerService.getOne(new LambdaQueryWrapper<BaseContainer>()
                                            .eq(BaseContainer::getContainerCode, containerCode));
                                }
                                mhbo.setContainerId(Long.valueOf(one.getId()));
                                mhbo.setPlcIP(conn.getId());
                                mhbo.setPointNo(startPoint);
                                mhbo.setTaskType("0");
                                mhbo.setTaskPath(startPoint);
                                Result<Long> booleanResult = iPutInOutStorageService.saveBusinBillTaskData(mhbo);
                                Long data = booleanResult.getData();
                                taskId = data;

                                //回填任务号
                                Map<String, Long> writeMap = new HashMap<>(1);
                                writeMap.put(valueType, taskId);
                                Map<String, Object> allMap = new HashMap<>(1);
                                allMap.put(writeTaskId, writeMap);
                                Boolean execWrite = plcReadAndWrite.execWrite(plcOperate, JsonUtil.toJSONString(allMap));
                                log.info("写入机械手输送线任务号" + taskId + "写入地址" + writeTaskId + "是否成功" + execWrite);
                                log.info("生成新任务：" + taskId + "治具编号：" + containerCode);
                                scheduledTasks.inTask(taskId, one.getId());
                                if (ObjectUtils.isNotEmpty(taskId)) {
                                    redisTemplate.opsForValue().set("autoTask", containerCode);
                                }
                            }
                        }
                    }
                    // TODO 电柜自动/手动判断人工下挂,暂时屏蔽,后续需要人工下挂时再打开,避免因为打手动频繁下发空治具出库至人工下挂点
//                    else{
//                        //给正在进行中的空治具添加新的目标点
//                        redisTemplate.opsForValue().set("PLCAuto",false);
//                        String dpsPoint = sysParameterService.selectConfigByKey(SecurityUtils.getCurrentBranchId(), ParameterConstants.ParameterSystem.blanking_point);
//                        BasePointDeviceQueryBo pointQueryBo = new BasePointDeviceQueryBo();
//                        pointQueryBo.setGroupNo(dpsPoint);
//                        List<BasePointDeviceVo> basePointDeviceVos = baseLocationPlcMapper.selectBasePointByGroupno(pointQueryBo);
//                        String point = basePointDeviceVos.get(0).getPointNo();
//                        List<BusinDataTask> businDataTasks = iBusinDataTaskService.queryinTask();
//                        if (businDataTasks.size()>0) {
//                            for (BusinDataTask businDataTask : businDataTasks) {
//                                businDataTask.setNewDestination(point);
//                                businDataTask.setTaskPath(point);
//                                BusinDpscontainerRecord dpscontainerRecord = businDpsContainerRecordMapper.selectByTaskid(String.valueOf(businDataTask.getId()));
//                                dpscontainerRecord.setPointNo(point);
//                                businDpsContainerRecordMapper.updateById(dpscontainerRecord);
//                            }
//                        }
//                        iBusinDataTaskService.updateBatchById(businDataTasks);
//
//                    }
                    break;
                case "3":
                    //立库输送线
                    //按照点位类型进行排序，统一读取所有点位类型德点位
                    Collections.sort(propertyList, new Comparator<WcsPlcProperty>() {
                        @Override
                        public int compare(WcsPlcProperty o1, WcsPlcProperty o2) {
                            return Integer.valueOf(o1.getTunnel()) - Integer.valueOf(o2.getTunnel());
                        }
                    });
                    //读取输送线是否：有料请求接料；请求入库业务
                    for (WcsPlcProperty plcProperty : propertyList) {
                        String tunnel = plcProperty.getTunnel();
                        //第一巷道
                        if ("01".equals(tunnel)) {
                            dpsTask(plcProperty, pointMap);
                        } else if ("02".equals(tunnel)) {
                            if (plcProperty.getPlcId() == 680) {
                                log.info("11111111111");
                            }
                            dpsTask(plcProperty, pointMap);
                        } else if ("03".equals(tunnel)) {
                            dpsTask(plcProperty, pointMap);
                        } else if ("04".equals(tunnel)) {
                            dpsTask(plcProperty, pointMap);
                        } else if ("05".equals(tunnel)) {
                            dpsTask(plcProperty, pointMap);
                        } else if ("06".equals(tunnel)) {
                            dpsTask(plcProperty, pointMap);
                        } else if ("99".equals(tunnel)) {
                            dpsTask(plcProperty, pointMap);
                        }
                    }
                    break;
                case "1":
                    //堆垛机
                    //实时监测堆垛机完成状态，调用库存处理逻辑
                    String readTaskPoint = null;
                    String readfinishPoint = null;
                    //处理状态是否完成,完成时改为true;把堆垛机状态清零
                    Boolean checkValue = false;

                    int readValue = 0;
                    for (WcsPlcProperty wcsPlcProperty : propertyList) {
                        if (wcsPlcProperty.getPointType().equals("4")) {
                            readfinishPoint = wcsPlcProperty.getAddress();
                        } else if (wcsPlcProperty.getPointType().equals("111")) {
                            readTaskPoint = wcsPlcProperty.getAddress();
                        } else if (wcsPlcProperty.getPointType().contains("35") || wcsPlcProperty.getPointType().contains("36")
                                || wcsPlcProperty.getPointType().contains("37") || wcsPlcProperty.getPointType().contains("42")
                                || wcsPlcProperty.getPointType().contains("43") || wcsPlcProperty.getPointType().contains("44")) {
                            if (pointMap.containsKey(wcsPlcProperty.getAddress())) {
                                redisTemplate.opsForValue().set(wcsPlcProperty.getPointType(), Integer.valueOf((String) pointMap.get(wcsPlcProperty.getAddress())));
                            }
                        }
                    }
                    if (pointMap.containsKey(readfinishPoint)) {
                        readValue = Integer.valueOf((String) pointMap.get(readfinishPoint));
                    }
                    if (pointMap.containsKey(readTaskPoint)) {
                        taskId = Long.valueOf((String) pointMap.get(readTaskPoint));
                    }
                    Long redisTaskId = 0L;
                    if (redisTemplate.opsForValue().get(RedisConstant.redisSTKWare + taskId) != null) {
                        Object temp = redisTemplate.opsForValue().get(RedisConstant.redisSTKWare + taskId);
                        redisTaskId = ObjectUtils.isNotEmpty(temp) ? Long.valueOf(temp.toString()) : 0L;
                    }
                    String tunnel = "";
                    //判断redis中是否已有此任务号，如果有则不再执行；
                    if (taskId != 0 && !redisTaskId.equals(taskId) && readValue == 1) {
                        log.info("堆垛机完成信号：" + readValue + " 对应的任务号：" + taskId + "开始处理库存");
                        //调用入库完成库存逻辑接口
                        BusinDataTask businDataTaskServiceById = iBusinDataTaskService.getById(taskId);
                        tunnel = businDataTaskServiceById.getTunnel();
                        String taskType = businDataTaskServiceById.getTaskType();
                        if (!taskType.equals("4") && !taskType.equals("5") && !taskType.equals("15")
                                && !taskType.equals("16") && !taskType.equals("21") && !taskType.equals("9")) {
                            //增加库存
                            Result<Boolean> booleanResult = iPutInOutStorageService.productDeposit(taskId);
                            //处理成功 返回状态，写入状态位为0
                            if (booleanResult.getCode() == HttpStatus.SUCCESS) {
                                checkValue = true;
                            }
                        } else if (taskType.equals(TaskTypeEnum.seat_adjustment.getValue())) {
                            // 处理货位调整的库存
                            BaseLocationQueryBo bo = new BaseLocationQueryBo();
                            bo.setLocationRow(businDataTaskServiceById.getFromRow());
                            bo.setLocationColumn(businDataTaskServiceById.getFromColumn());
                            bo.setLayer(businDataTaskServiceById.getFromLayer());
                            List<BaseLocationVo> BaseLocationVoListOld = iBaseLocationService.queryList(bo);

                            bo = new BaseLocationQueryBo();
                            bo.setLocationRow(businDataTaskServiceById.getToRow());
                            bo.setLocationColumn(businDataTaskServiceById.getToColumn());
                            bo.setLayer(businDataTaskServiceById.getToLayer());

                            List<BaseLocationVo> BaseLocationVoListNew = iBaseLocationService.queryList(bo);
                            businDataTaskServiceById.setTaskStatus("2");
                            iBusinDataTaskService.updateById(businDataTaskServiceById);
                            BaseLocationVo baseLocationVo = BaseLocationVoListOld.get(0);
                            BaseLocation baseLocation = BeanUtil.toBean(baseLocationVo, BaseLocation.class);
                            baseLocation.setLocationStatus("0");
                            baseLocation.setUpdateTime(DateUtils.getNowDate());
                            boolean oldbool = iBaseLocationService.updateById(baseLocation);
                            log.info("更新旧的货位状态：" + oldbool);

                            BaseLocationVo baseLocationVoNew = BaseLocationVoListNew.get(0);
                            BaseLocation baseLocationNew = BeanUtil.toBean(baseLocationVoNew, BaseLocation.class);
                            //把原始貨位的狀態給新的貨位
                            baseLocationNew.setLocationStatus(baseLocationVo.getLocationStatus());
                            baseLocationNew.setUpdateTime(DateUtils.getNowDate());
                            boolean newbool = iBaseLocationService.updateById(baseLocationNew);
                            log.info("更新新的货位状态：" + newbool);
                            boolean changeType = iBusinDataTaskDetailService.updateInfoByLocationCode(BaseLocationVoListOld.get(0).getId(), BaseLocationVoListNew.get(0).getId()) > 0;
                            if (changeType) {
                                checkValue = true;
                            }
                        } else if (TaskTypeEnum.normal_out.getValue().equals(taskType)
                                || TaskTypeEnum.urgent_out.getValue().equals(taskType)
                                || TaskTypeEnum.abnormal_delivery.getValue().equals(taskType)
                                || TaskTypeEnum.punching_out.getValue().equals(taskType)
                                || TaskTypeEnum.replenish_out.getValue().equals(taskType)
                                || TaskTypeEnum.named_loc.getValue().equals(taskType)) {
                            //处理 4正常出库  5紧急出库 17异常出库 21冲孔出库  10补货出库   库存
                            log.info("扣减库存的任务类型：" + taskType);
                            Boolean delStock = iBusinPickupService.subtractStockDetailByLocation(businDataTaskServiceById);
                            log.info("扣减库存的结果：" + delStock);
                            if (delStock) {
                                checkValue = true;
                            }
                        } else {
                            if (taskType.equals(TaskTypeEnum.emptyContainer_out.getValue())) {
                                //处理 15空治具出库   库存
                                BusinDpscontainerRecord oneByTask = businDpsContainerRecordMapper.selectByTaskid(String.valueOf(taskId));
                                oneByTask.setIsState("1");
                                businDpsContainerRecordMapper.updateById(oneByTask);
//                                Boolean delStock = iBusinPickupService.subtractStockDetailByLocation(businDataTaskServiceById);
//                                log.info("空治具出库任务号："+businDataTaskServiceById.getId()+"处理的货位id："+businDataTaskServiceById.getLocationId()+"结果："+ delStock);
//                                if (delStock){
//                                    checkValue=true;
//                                }
                            }
                            Map<String, Object> writeMap = new HashMap<>(1);
                            writeMap.put("SHORT", 0);
                            Map<String, Object> allMap = new HashMap<>(1);
                            allMap.put(readfinishPoint, writeMap);
                            if (plcReadAndWrite.execWrite(plcOperate, JsonUtil.toJSONString(allMap))) {
                                //请求成功，记录已下发
                                redisTemplate.opsForValue().set(RedisConstant.redisSTKWare + taskId, taskId);
                            }
                            checkValue = true;
                        }
                    } else {
                        log.info("任务命令已下发，任务号：" + taskId);
                    }

                    if (checkValue) {
                        log.info("堆垛机完成的任务号：" + taskId);
                        Map<String, Object> writeMap = new HashMap<>(1);
                        writeMap.put("SHORT", 0);
                        Map<String, Object> allMap = new HashMap<>(1);
                        allMap.put(readfinishPoint, writeMap);
                        if (plcReadAndWrite.execWrite(plcOperate, JsonUtil.toJSONString(allMap))) {
                            //请求成功，记录已下发
                            redisTemplate.opsForValue().set(RedisConstant.redisSTKWare + taskId, taskId);
                        }
                        redisTemplate.opsForValue().set("stackerLock:" + tunnel, "false");
                    }
                    break;
                case "4":
                    //冲孔机完成按钮
                    //调度AGV
                    BasePunchRecordQueryBo punchRecordQueryBo = new BasePunchRecordQueryBo();
                    punchRecordQueryBo.setTaskCode(taskId);
                    BasePunchRecord basePunchRecord = iBasePunchRecordService.selectBasePunchRecord(punchRecordQueryBo);
                    //下料按钮 更新状态为1 冲孔中；上料按钮 更新状态为2 已完成
                    basePunchRecord.setIsState("1");
                    basePunchRecord.setUpdateTime(DateUtils.getNowDate());
                    iBasePunchRecordService.updateById(basePunchRecord);

                    /**
                     * 出库完成
                     * 按下PLC完成按钮
                     * 减去库存，更新库存状态，根据及货位查找产品并更新
                     * 出库完成，空治具流向
                     */
                    //出库完成减去库存
                    Result<Boolean> booleanResult = iPutInOutStorageService.reduceInventory(taskId);
                    //获取治具编号
                    BusinDataTask businDataTask = iBusinDataTaskService.getById(taskId);
                    //出库组装区接驳点位 TODO
                    String fromPoint = "";
                    iBusinEnptyContainerService.emptyContainerFlowDir(fromPoint, businDataTask.getContainerId(), "", null);
                    break;
                case "5":
                    String arriveAddres = "";
                    String arrivepoint = "";
                    //出库位置按钮合
                    for (WcsPlcProperty wcsPlcProperty : propertyList) {
                        if (wcsPlcProperty.getPointType().equals("10")) {
                            arriveAddres = wcsPlcProperty.getAddress();
                            arrivepoint = wcsPlcProperty.getRelPoint();
                        }
                    }
                    if (pointMap.containsKey(arriveAddres) && Boolean.valueOf(pointMap.get(arriveAddres).toString())) {
                        //查询对应出库点位已完成的任务
                        BusinDataTask businTask = iBusinDataTaskService.getOne(new LambdaQueryWrapper<BusinDataTask>()
                                .eq(BusinDataTask::getTaskPath, arriveAddres)
                                .eq(BusinDataTask::getTaskStatus, "2"));
                        if (ObjectUtils.isNotEmpty(businTask)) {
                            //出库完成减去库存出库组装区接驳点位
                            Result<Boolean> resultboolean = iPutInOutStorageService.reduceInventory(businTask.getId());
                            //将货位状态改为0既货位为空
                            BaseLocation baseLocation = iBaseLocationService.getById(businTask.getLocationId());
                            baseLocation.setLocationStatus("0");
                            iBaseLocationService.updateById(baseLocation);
                            iBusinEnptyContainerService.emptyContainerFlowDir(businTask.getTaskPath(), businTask.getContainerId(), businTask.getAgvNo(), null);
                        }
                    }
                    break;
                default:
                    log.error("无匹配的设备类型");
                    break;
            }

            LocalTime end = LocalTime.now();
            Duration between = Duration.between(start, end);
            long seconds = between.getSeconds() % 60;
            log.info("执行plctask用时：" + seconds);

        } catch (Exception e) {
            e.printStackTrace();
            log.error("plc======================" + e.getMessage());
        }
    }


    /**
     * 立库输送线业务信息
     *
     * @param plcProperty
     * @param pointMap
     */
    public void dpsTask(WcsPlcProperty plcProperty, Map<String, Object> pointMap) {
        Long stkPlcId = 0L;
        //有料请求接料
        String requestPoint = null;
        String requestTaskId = null;
        String requestPointTwe = null;
        //出库接驳，根据设备类型获取
        String outboundPoint;

        //入库请求,需要根据2个点位进行判断，其中一个为true,则执行堆垛机指令
        String requestPutOne = null;
        String requestPutTwo = null;

        String requestPutTaskIdOne = null;
        String requestPutTaskIdTwo = null;

//        立库输送线放货完成后删除货位
        String performAddress = null;
        String performrelPoint = null;

        String Overonaddress = "";

        String taskIdPoint = "";
        Long relDev = null;

        //前杠正常放行
        String frontPoint = "";
        String frontPointValueType = "";

        //后杠正常放行
        String afterPoint = "";
        String afterPointValueType = "";

        String pointType = plcProperty.getPointType();
        //有料请求接料
        if (PlcPropertyEnum.five.getValue().equals(pointType)) {
            requestPoint = plcProperty.getAddress();
            requestPointTwe = plcProperty.getRelPoint();
        }
        //请求接料任务ID即出库任务ID
        if (PlcPropertyEnum.twentytwo.getValue().equals(pointType)) {
            requestTaskId = plcProperty.getAddress();
        }
        //请求入库状态
        if (PlcPropertyEnum.two.getValue().equals(pointType)) {
            requestPutOne = plcProperty.getAddress();
            requestPutTwo = plcProperty.getRelPoint();
        }

        //请求入库任务编号
        if (PlcPropertyEnum.twentyone.getValue().equals(pointType)) {
            requestPutTaskIdOne = plcProperty.getAddress();
            requestPutTaskIdTwo = plcProperty.getRelPoint();
        }
        //放料完成,删除对应点位货架(one是是否允许放货)
        if (PlcPropertyEnum.one.getValue().equals(pointType)) {
            performAddress = plcProperty.getAddress();
            performrelPoint = plcProperty.getRelPoint();
        }
        //前杠正常放行
        if ("23".equals(pointType)) {
            frontPoint = plcProperty.getAddress();
            frontPointValueType = plcProperty.getValueType();
        }

        //后杠正常放行
        if ("25".equals(pointType)) {
            afterPoint = plcProperty.getAddress();
            afterPointValueType = plcProperty.getValueType();
        }

        //立库输送线允许放货后删除货架
//        if (pointMap.containsKey(performAddress)&&Boolean.valueOf(String.valueOf(pointMap.get(performAddress)))){
//            log.error("删除货架点位为:"+performAddress);
//            log.error("删除货架对应DB点位状态:"+Boolean.valueOf(String.valueOf(pointMap.get(performAddress))));
//            log.error("删除货架agv地图对应点位:"+performrelPoint);
//            Map map = new HashMap();
//            map.put("posId",performrelPoint);
//            rcsUtil.openRun(map);
//        }

        Long taskId = 0L;
        //有料请求接料，给AGV下发搬运任务
        if (pointMap.containsKey(requestPoint) && Boolean.valueOf(String.valueOf(pointMap.get(requestPoint)))) {
            log.info("有料请求接料,接收到PLC出库信号！");
            relDev = Long.valueOf(plcProperty.getRelDev());
            //根据设备ID获取设备对应的巷道信息，及设备关联的点位；
            BasePointQueryBo queryBo = new BasePointQueryBo();
            queryBo.setDevCode(relDev);
            BasePointVo basePointVo = iBasePointService.selectBasePointByQuery(queryBo);
            log.info("关联设备对应点位:" + basePointVo.getPointNo());
            if (basePointVo == null) {
                return;
            }
            //到达组装线等待上报点进行的业务处理
            String reportPointGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.report_point);
            BasePointDeviceQueryBo pointReportQueryBo = new BasePointDeviceQueryBo();
            String reportPoint = "";
            pointReportQueryBo.setGroupNo(reportPointGroup);
            BasePointDeviceVo reportPointDeviceOut = basePointDeviceMapper.selectBasePointByGroupno(pointReportQueryBo);
            if (ObjectUtils.isEmpty(reportPointDeviceOut)) {
                log.error("请维护组装线上报点");
                return;
            }
            reportPoint = reportPointDeviceOut.getPointNo();
            if (requestPointTwe != null) {
                taskId = Long.valueOf((String) pointMap.get(requestPointTwe));
            }
            //从redis中验证是否已经下发任务
            BusinDataTask redisTask = (BusinDataTask) redisTemplate.opsForValue().get(RedisConstant.redisReqMate + taskId);
            if (redisTask != null) {
                return;
            }
            log.info("立库输送线读取的任务号:" + taskId);
            if (taskId != null && taskId != 0) {
                //获取任务信息
                BusinDataTask businDataTask = iBusinDataTaskService.getById(taskId);
                if (businDataTask == null) {
                    log.info("当前任务号未查询到任务信息：" + taskId);
                    return;
                }
                //AGV节点信息
                List<String> agvPoints = new ArrayList<>();
                Map<String, String> snPointMap = new HashMap<>(3);
                int agvTaskType = 0;

                agvPoints.add(basePointVo.getPointNo());
                agvPoints.add(basePointVo.getHandshakePoint());

                snPointMap.put("1", basePointVo.getPointNo());
                snPointMap.put("2", basePointVo.getHandshakePoint());

                if ("4".equals(businDataTask.getTaskType()) || "5".equals(businDataTask.getTaskType())) {
                    agvPoints.add(reportPoint);
                    agvPoints.add(businDataTask.getTaskPath());

                    snPointMap.put("3", reportPoint);
                    snPointMap.put("4", businDataTask.getTaskPath());
                } else if (TaskTypeEnum.abnormal_delivery.getValue().equals(businDataTask.getTaskType())) {
                    // TODO 人车分流相关  需要修改对应的任务类型为 33   需要添加在RCS地图上添加对应的点位 abnormal_wait_point
                    String abnormalWaitPintGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.abnormalWaitPint);
                    BasePointDeviceQueryBo abnormalWaitPintBo = new BasePointDeviceQueryBo();
                    abnormalWaitPintBo.setGroupNo(abnormalWaitPintGroup);
                    BasePointDeviceVo abnormalWaitPintDeviceVo = basePointDeviceMapper.selectBasePointByGroupno(abnormalWaitPintBo);

                    agvPoints.add(abnormalWaitPintDeviceVo.getPointNo());
                    agvPoints.add(abnormalWaitPintDeviceVo.getPointNo());
                    agvPoints.add(businDataTask.getTaskPath());

                    snPointMap.put("3", abnormalWaitPintDeviceVo.getPointNo());
                    snPointMap.put("4", abnormalWaitPintDeviceVo.getPointNo());
                    snPointMap.put("5", businDataTask.getTaskPath());

                    agvTaskType = Integer.valueOf(abnormalWaitPintDeviceVo.getIsDown());
                } else if (businDataTask.getTaskType().equals(TaskTypeEnum.relocation.getValue())) {
                    // TODO 跨巷道移库AGV的模板尚未提供
                } else {
                    agvPoints.add(businDataTask.getTaskPath());
                    snPointMap.put("3", businDataTask.getTaskPath());

                    if ("15".equals(businDataTask.getTaskType()) && "KW16".equals(businDataTask.getTaskPath())) {
                        agvPoints.add("KW17");
                        snPointMap.put("4", "KW17");
                    }
                }

                businDataTask.setPoints(JsonUtil.toJSONString(snPointMap));
                businDataTask.setPlcId(basePointVo.getPlcId());
                //立库输送线id
                businDataTask.setDpsNoOne(Long.valueOf(isysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.LK_plc_id)));
                //呼叫AGV
                AGVMoveBo bo = new AGVMoveBo();
                bo.setPoints(agvPoints);
                bo.setTaskId(businDataTask.getId());
                //任务类型
                //TODO 测试注释   要打开     修改 数据库base_point_group 中 立库输送线出  对应的 is_down 为31    24  只有一个上报点位。   31  有俩上报点位
                bo.setTaskType(Integer.valueOf(basePointVo.getIsDown()));

                if ("15".equals(businDataTask.getTaskType()) && "KW16".equals(businDataTask.getTaskPath())) {
                    bo.setTaskType(RCSTaskTypeEnum.A_TO_B_HAND_PUT1.getValue());
                    businDataTask.setPlcId(30L);
                }
                if ("15".equals(businDataTask.getTaskType()) && "KW20".equals(businDataTask.getTaskPath())) {
                    bo.setTaskType(RCSTaskTypeEnum.A_TO_B_NO_PUT.getValue());
//                    businDataTask.setPlcId(30L);
                }
                if (("15".equals(businDataTask.getTaskType()) || "5".equals(businDataTask.getTaskType())) && "Urgent_out".equals(businDataTask.getTaskPath())) {
                    bo.setTaskType(24);
                    businDataTask.setPlcId(30L);
                }
                if (TaskTypeEnum.abnormal_delivery.getValue().equals(businDataTask.getTaskType())) {
                    bo.setTaskType(agvTaskType);
                    businDataTask.setPlcId(30L);
                }

                if ("21".equals(businDataTask.getTaskType())
                        || TaskTypeEnum.replenish_out.getValue().equals(businDataTask.getTaskType())) {
                    bo.setTaskType(24);
                    businDataTask.setPlcId(30L);
                }

                //目的点位
//                bo.setToLocation(businDataTask.getTaskPath());
                Result<Boolean> booleanResult = rcsUtil.moveByAGV(bo);
                if (booleanResult.getCode() == HttpStatus.SUCCESS) {
                    //更新任务状态
                    businDataTask.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
                    businDataTask.setTaskStarttime(DateUtils.getNowDate());
                    businDataTask.setIsDown(bo.getTaskType() + "");
                    iBusinDataTaskService.updateById(businDataTask);
                    redisTemplate.opsForValue().set(RedisConstant.redisReqMate + taskId, businDataTask);
                    //扣减巷道任务数
                    tunnelTaskUtil.subOutboundTaskNum(businDataTask.getTunnel());
                }
            }
        }

        //请求入库，给堆垛机下发命令
        if (pointMap.containsKey(requestPutOne) || pointMap.containsKey(requestPutTwo)) {
            if (Boolean.valueOf(String.valueOf(pointMap.get(requestPutOne))) || 0 != Integer.valueOf(String.valueOf(pointMap.get(requestPutTwo)))) {
                taskId = Long.valueOf((String) pointMap.get(requestPutTwo));
                if (taskId == 0) {
                    taskId = Long.valueOf((String) pointMap.get(requestPutTaskIdTwo));
                }
                //从redis中验证是否已经下发任务
                BusinDataTask redisTask = (BusinDataTask) redisTemplate.opsForValue().get(RedisConstant.redisReqWare + taskId);
                if (redisTask != null) {
                    return;
                }

                //获取任务ID
                BusinDataTask businDataTask = iBusinDataTaskService.getById(taskId);
                String toLayer = businDataTask.getToLayer();
                String toColumn = businDataTask.getToColumn();
                String toRow = businDataTask.getToRow();
                //获取堆垛机
                BasePointDeviceQueryBo pointQueryBo = new BasePointDeviceQueryBo();
                pointQueryBo.setDevType("1");
                pointQueryBo.setTunnel(businDataTask.getTunnel());
                BaseDevicePlcVo baseDevicePlcVo = baseLocationPlcMapper.selectBaseDevicePlc(pointQueryBo);
                stkPlcId = baseDevicePlcVo.getPlcId();
                PlcOperate stkOperate = plcInit.getPlcOperateByIp(baseDevicePlcVo.getPlcIp());

                List<WcsPlcProperty> propertyList = iWcsPlcPropertyService.getWcsPlcPropertyByPlcId(stkPlcId);
                String plcTaskId = "";
                String plcToRow = "";
                String plcToColumn = "";
                String plcToLayer = "";
                String plcHs = "";
                String plcml = "";
                WcsPlcConnect plcConnect = iWcsPlcConnectService.getById(stkPlcId);
                //堆垛机是否空闲
                String readNullPoint = "";
                for (WcsPlcProperty stkProperty : propertyList) {
                    //获取要堆垛机要写入的点位
                    if (stkProperty.getPointType().equals("101")) {
                        plcTaskId = stkProperty.getAddress();
                    } else if (stkProperty.getPointType().equals("108")) {
                        plcToRow = stkProperty.getAddress();
                    } else if (stkProperty.getPointType().equals("109")) {
                        plcToColumn = stkProperty.getAddress();
                    } else if (stkProperty.getPointType().equals("110")) {
                        plcToLayer = stkProperty.getAddress();
                    } else if (stkProperty.getPointType().equals("103")) {
                        plcHs = stkProperty.getAddress();
                    } else if (stkProperty.getPointType().equals("102")) {
                        plcml = stkProperty.getAddress();
                    } else if (stkProperty.getPointType().equals("12")) {
                        readNullPoint = stkProperty.getAddress();
                    } else if (stkProperty.getPointType().equals("4")) {
                        Overonaddress = stkProperty.getAddress();
                    }
                }
                //根据连接的plcId获取属性
                PLCReadAndWrite plcReadAndWriteD = new PLCReadAndWrite();
                Map<String, Object> pointDMap = plcReadAndWriteD.readPlcData(stkOperate, plcConnect.getPointTables());
                if (pointDMap.containsKey(readNullPoint) && Boolean.valueOf(pointDMap.get(readNullPoint).toString()) && pointDMap.get(Overonaddress).equals("0")) {
                    //请求入库成功 给堆垛机下命令判断是否 加锁 加锁则返回
                    if (ObjectUtils.isNotEmpty(redisTemplate.opsForValue().get("stackerLock:" + businDataTask.getTunnel()))
                            && redisTemplate.opsForValue().get("stackerLock:" + businDataTask.getTunnel()).toString().equals("true")) {
                        return;
                    } else {
                        redisTemplate.opsForValue().set("stackerLock:" + businDataTask.getTunnel(), "true");
                    }
                    //给堆垛机写命令
                    Map<String, Object> allMap = new HashMap<>(1);
                    Map<String, Object> plcTaskIdMap = new HashMap<>(1);
                    plcTaskIdMap.put("INTEGER", taskId);
                    allMap.put(plcTaskId, plcTaskIdMap);
                    Map<String, Object> plcToRowMap = new HashMap<>(1);
                    plcToRowMap.put("SHORT", toRow);
                    allMap.put(plcToRow, plcToRowMap);
                    Map<String, Object> plcToColumnMap = new HashMap<>(1);
                    plcToColumnMap.put("SHORT", toColumn);
                    allMap.put(plcToColumn, plcToColumnMap);
                    Map<String, Object> plcToLayerMap = new HashMap<>(1);
                    plcToLayerMap.put("SHORT", toLayer);
                    allMap.put(plcToLayer, plcToLayerMap);
                    Map<String, Object> plcHsMap = new HashMap<>(1);
                    plcHsMap.put("SHORT", 1);
                    allMap.put(plcHs, plcHsMap);
                    Map<String, Object> plcMLMap = new HashMap<>(1);
                    plcMLMap.put("Short", 1);
                    allMap.put(plcml, plcMLMap);

                    PLCReadAndWrite plcReadAndWrite = new PLCReadAndWrite();
                    if (plcReadAndWrite.execWrite(stkOperate, JsonUtil.toJSONString(allMap))) {
                        //请求成功，记录已下发
                        redisTemplate.opsForValue().set(RedisConstant.redisReqWare + taskId, businDataTask);
                    }
                    //解锁
                    //redisTemplate.opsForValue().set("stackerLock:"+taskId, "false");
                }
            }
        }

        Map taskidMap = new HashMap(1);
        Map TaskwriteMap = new HashMap(1);

        BasePointDeviceQueryBo pointQueryBo = new BasePointDeviceQueryBo();
        pointQueryBo.setDevType("3");
        BaseDevicePlcVo baseDevicePlcVo = baseLocationPlcMapper.selectBaseDevicePlc(pointQueryBo);

        //组装线前杠正常放行
        if (pointMap.containsKey(frontPoint) && Boolean.valueOf(String.valueOf(pointMap.get(frontPoint)))) {
            log.info("组装线前杠正常放行");
            PlcOperate plcOperate = plcInit.getPlcOperateByIp(baseDevicePlcVo.getPlcIp());
            TaskwriteMap.put(frontPointValueType, "False");
            taskidMap.put(frontPoint, TaskwriteMap);
            PLCReadAndWrite plcReadAndWrite = new PLCReadAndWrite();
            Boolean aBoolean = plcReadAndWrite.execWrite(plcOperate, JSON.toJSONString(taskidMap));

            iBusinPickupService.savePickupRecordByAssemblyLine("front");
        }
        //组装线后杠正常放行
        //组装线现分为一个点位，暂时注释，后续打开
        if (pointMap.containsKey(afterPoint) && Boolean.valueOf(String.valueOf(pointMap.get(afterPoint)))) {
            log.info("组装线后杠正常放行");
            PlcOperate plcOperate = plcInit.getPlcOperateByIp(baseDevicePlcVo.getPlcIp());
            TaskwriteMap.put(afterPointValueType, "False");
            taskidMap.put(afterPoint, TaskwriteMap);
            PLCReadAndWrite plcReadAndWrite = new PLCReadAndWrite();
            Boolean aBoolean = plcReadAndWrite.execWrite(plcOperate, JSON.toJSONString(taskidMap));

            iBusinPickupService.savePickupRecordByAssemblyLine("after");
        }

    }

    private void doDevStatus(PlcOperate plcOperate, String tunnel) {
        try {

            String freeOrRun = "DB20.0.2";
            String fault = "DB20.4.7";

            Map addreesMap = new HashMap();
            addreesMap.put(freeOrRun, "Boolean");
            addreesMap.put(fault, "Boolean");

            PLCReadAndWrite plcReadAndWrite = new PLCReadAndWrite();
            Map<String, Object> pointMap = plcReadAndWrite.readPlcData(plcOperate, JsonUtil.toJSONString(addreesMap));
            //空闲运行点位值

            BusinPlcStatus businPlcStatus = new BusinPlcStatus();
            businPlcStatus.setTunnel(tunnel);
            if (pointMap.containsKey(freeOrRun)) {
                String stkFreeOrRun = pointMap.get(freeOrRun).toString();
                //1空闲 0运行中
                if (stkFreeOrRun.equals("true")) {
                    businPlcStatus.setStkFree("1");
                } else {
                    businPlcStatus.setStkRun("1");
                }
            }

            if (pointMap.containsKey(fault)) {
                String stkFault = pointMap.get(fault).toString();
                if (stkFault.equals("true")) {
                    businPlcStatus.setStkFault("1");
                } else {
                    businPlcStatus.setStkFault("0");
                }
            }
            redisTemplate.opsForValue().set(RedisConstant.redisStkStatus + tunnel, businPlcStatus);

        } catch (Exception e) {
            log.error("处理设备状态{}" + e.getMessage());
        }
    }


    //    @Scheduled(cron = " 0/5 * * * * ? ")
    public void CharigingPile() {
        WcsPlcConnect wcsPlcConnect = iWcsPlcConnectService.getById("39");
        PlcOperate automation = plcInit.getPlcOperateByIp(wcsPlcConnect.getPlcIp());
        Long plcId = wcsPlcConnect.getId();
        PLCReadAndWrite plcReadAndWrite = new PLCReadAndWrite();
        //获取所有agv的状态
        Map mapIdMap = new HashMap();
        mapIdMap.put("mapId", 1);
        String mapId = JSON.toJSONString(mapIdMap);
        Result result = rcsUtil.rcsRobotsStates(mapId);
        Object agvobj = result.getData();
        String AGVstr = JSONUtils.toJSONString(agvobj);
        List<Object> agvlist = JSONArray.parseArray(AGVstr);

        List<WcsPlcProperty> propertyList = iWcsPlcPropertyService.getWcsPlcPropertyByPlcId(plcId);
        List<WcsPlcProperty> collect = propertyList.stream().filter(e -> e.getPointType().equals("one") || e.getPointType().equals("two") || e.getPointType().equals("three") || e.getPointType().equals("four") || e.getPointType().equals("five")).collect(Collectors.toList());
        String leftX = "";
        String leftY = "";
        String rightX = "";
        String rightY = "";
        String Address = "";
        String valueType = "";
        for (WcsPlcProperty wcsPlcProperty : collect) {
            Boolean TrueValue = false;
            Map allwriteMap = new HashMap(1);
            Map writeMap = new HashMap(1);
            Address = wcsPlcProperty.getAddress();
            valueType = wcsPlcProperty.getValueType();
            Map map = (Map) JSON.parse(wcsPlcProperty.getRelDev());
            if (ObjectUtils.isNotEmpty(map)) {
                leftX = String.valueOf(map.get("leftX"));
                leftY = String.valueOf(map.get("leftY"));
                rightX = String.valueOf(map.get("rightX"));
                rightY = String.valueOf(map.get("rightY"));
                for (Object object : agvlist
                ) {
                    AgvMessageVo agvMessageVo = BeanUtil.toBean(object, AgvMessageVo.class);
                    if (agvMessageVo.getAgvState().equals("charging")) {
                        Position position = agvMessageVo.getPosition();
                        if (position.getX().compareTo(new BigDecimal(leftX)) > 0 && position.getX().compareTo(new BigDecimal(rightX)) < 0) {
                            if (position.getY().compareTo(new BigDecimal(leftY)) > 0 && position.getY().compareTo(new BigDecimal(rightY)) < 0) {
                                TrueValue = true;
                            }
                        }
                    }
                }

                if (TrueValue) {
                    writeMap.put(valueType, "True");
                    allwriteMap.put(Address, writeMap);
                } else {
                    writeMap.put(valueType, "False");
                    allwriteMap.put(Address, writeMap);
                }


                PLCUtil plcUtil = new PLCUtil();
                String temp = plcUtil.readPlc(Address, valueType, automation, 0);
                if (!temp.equals(TrueValue.toString().toLowerCase())) {
                    Boolean write = plcReadAndWrite.execWrite(automation, JSON.toJSONString(allwriteMap));
                    int i = 0;
                    while (!write && i < 10) {
                        write = plcReadAndWrite.execWrite(automation, JSON.toJSONString(allwriteMap));
                        i++;
                    }
                }

//                log.error("写入充电桩充电中成功:写入点位:" + Address + "      写入点位类型为:" + valueType + "        写入值为:" + writeMap.get(valueType));
            }
        }
    }


}
