package org.nl.acs.device_driver.basedriver.slit_two_manipulator;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.acs.device.domain.Device;
import org.nl.acs.device.service.DeviceService;
import org.nl.acs.device_driver.DeviceDriver;
import org.nl.acs.device_driver.RouteableDeviceDriver;
import org.nl.acs.device_driver.basedriver.siemens_conveyor.SiemensConveyorDeviceDriver;
import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver;
import org.nl.acs.device_driver.driver.ExecutableDeviceDriver;
import org.nl.acs.ext.wms.service.AcsToWmsService;
import org.nl.acs.instruction.domain.Instruction;
import org.nl.acs.instruction.service.InstructionService;
import org.nl.acs.log.service.DeviceExecuteLogService;
import org.nl.acs.monitor.DeviceStageMonitor;
import org.nl.acs.opc.DeviceAppService;
import org.nl.acs.opc.DeviceAppServiceImpl;
import org.nl.acs.route.service.RouteLineService;
import org.nl.acs.task.service.TaskService;
import org.nl.acs.task.service.dto.TaskDto;
import org.nl.common.exception.BadRequestException;
import org.nl.config.SpringContextHolder;
import org.openscada.opc.lib.da.Server;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * 分切双工位行架机械手
 */
@Slf4j
@Data
@RequiredArgsConstructor
public class SlitTwoManipulatorDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver, DeviceStageMonitor {
    protected ItemProtocol itemProtocol = new ItemProtocol(this);
    @Autowired
    InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl");
    @Autowired
    DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl");
    @Autowired
    RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl");
    @Autowired
    TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl");
    @Autowired
    AcsToWmsService acsToWmsService = SpringContextHolder.getBean("acsToWmsServiceImpl");
    @Autowired
    DeviceAppService deviceAppservice = SpringContextHolder.getBean(DeviceAppServiceImpl.class);

    DeviceExecuteLogService logServer = SpringContextHolder.getBean("deviceExecuteLogServiceImpl");

    //分切行架机械手是否禁用 0否 1是
    private int is_disable = 0;

    //工作模式
    int mode = 0;
    int last_mode = 0;
    //设备状态
    int status = 0;
    int last_status = 0;
    //前后工位光电信号
    int move1 = 0;
    int last_move1 = 0;
    int move2 = 0;
    int last_move2 = 0;
    //前后工位动作信号
    int action1 = 0;
    int last_action1 = 0;
    int action2 = 0;
    int last_action2 = 0;
    //报警信号
    int error = 0;
    int last_error = 0;
    //行走列
    int walk_y = 0;
    int last_walk_y = 0;
    //任务类型
    int type = 0;
    int last_type = 0;
    //前后工位任务号
    int task1 = 0;
    int last_task1 = 0;
    int task2 = 0;
    int last_task2 = 0;


    Boolean isonline = true;
    //前工位申请任务请求标记
    Boolean requireSucess = false;

    int hasGoods = 0;
    String message = null;
    Boolean iserror = false;

    int branchProtocol = 0;

    //暂定 0就绪 1请求取货 2取货完成 3请求放货 4放货完成 5取货完成离开 6放货完成离开 7请求进入区域 8请求离开区域
    int flag;

    //前工位任务执行当前步骤
    //0未执行 1更改指令状态 2下发电气任务信息 3前工位允许取货 4前工位取货完成 5前工位允许放货 6放货完成
    int now_steps_type1 = 0;
    //后工位当前执行步骤
    //0未执行 1更改指令状态 2下发电气任务信息 3后工位允许取货4后工位取货完成 5后工位允许放货 6放货完成
    int now_steps_type2 = 0;
    //双工位任务当前执行步骤
    //0未执行 1更改指令状态 2下发电气任务信息 3后工位允许取货 4后工位取货完成 5前工位允许取货 6前工位取货完成 7后工位允许放货 8后工位放货完成 9前工位允许放货 10前工位放货完成
    int now_steps_type3 = 0;

    String device_code;


    //请求超时时间
    private int instruction_require_time_out = 3000;


    //后工位申请任务请求时间
    private Date instruction_require_time = new Date();
    //前工位申请任务请求时间
    private Date instruction_head_time = new Date();

    String notCreateTaskMessage = "";
    String notCreateInstMessage = "";
    String feedMessage = "";


    @Override
    public Device getDevice() {
        return this.device;
    }


    @Override
    public synchronized void execute(){
        String message = null;
        try {
            device_code = this.getDeviceCode();
            mode = this.itemProtocol.getMode();
            status = this.itemProtocol.getStatus();
            move1 = this.itemProtocol.getMove1();
            move2 = this.itemProtocol.getMove2();
            action1 = this.itemProtocol.getAction1();
            action2 = this.itemProtocol.getAction2();
            walk_y = this.itemProtocol.getWalk_y();
            error = this.itemProtocol.getError();
            type = this.itemProtocol.getType();
            task1 = this.itemProtocol.getTask1();
            task2 = this.itemProtocol.getTask2();

            if (mode != last_mode) {
                if (mode == 2) {
                    logServer.deviceExecuteLog(device_code, "", "", "开始请求标记复位`此时请求标记值为:" + requireSucess);
                    requireSucess = false;
                    logServer.deviceExecuteLog(device_code, "", "", "请求标记复位成功`此时请求标记值为:" + requireSucess);
                }
                logServer.deviceItemValue(this.device_code, "mode", String.valueOf(mode));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号mode：" + last_mode + "->" + mode);
            }
            if (type != last_type) {
                logServer.deviceItemValue(this.device_code, "type", String.valueOf(type));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号type：" + last_type + "->" + type);
            }
            if (error != last_error) {
                logServer.deviceItemValue(this.device_code, "error", String.valueOf(error));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号error：" + last_error + "->" + error);
            }
            if (status != last_status) {
                logServer.deviceItemValue(this.device_code, "status", String.valueOf(status));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号status：" + last_status + "->" + status);
            }
            if (move1 != last_move1) {
                logServer.deviceItemValue(this.device_code, "move1", String.valueOf(move1));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号move1：" + last_move1 + "->" + move1);
            }
            if (move2 != last_move2) {
                logServer.deviceItemValue(this.device_code, "move2", String.valueOf(move2));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号move2：" + last_move2 + "->" + move2);
            }
            if (action1 != last_action1) {
                logServer.deviceItemValue(this.device_code, "action1", String.valueOf(action1));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号action1：" + last_action1 + "->" + action1);
            }
            if (action2 != last_action2) {
                logServer.deviceItemValue(this.device_code, "action2", String.valueOf(action2));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号action2：" + last_action2 + "->" + action2);
            }
            if (walk_y != last_walk_y) {
                logServer.deviceItemValue(this.device_code, "walk_y", String.valueOf(walk_y));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号walk_y：" + last_walk_y + "->" + walk_y);
            }
            if (task1 != last_task1) {
                logServer.deviceItemValue(this.device_code, "task1", String.valueOf(task1));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号task1：" + last_task1 + "->" + task1);
            }
            if (task2 != last_task2) {
                logServer.deviceItemValue(this.device_code, "task2", String.valueOf(task2));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号task2：" + last_task2 + "->" + task2);
            }

            //单任务 前工位任务更新指令状态
            if (task1 > 0 && type == 1) {
                Instruction inst1 = instructionService.findByCodeFromCache(String.valueOf(task1));
                if (inst1 != null) {
                    if (StrUtil.equals(inst1.getInstruction_status(), "0")) {
                        //当前执行步骤为更新任务状态
                        inst1.setInstruction_status("1");
                        inst1.setExecute_device_code(this.getDevice_code());
                        instructionService.update(inst1);
//                        TaskDto taskDto = taskserver.findByCodeFromCache(inst1.getTask_code());
//                        if (!ObjectUtil.isEmpty(taskDto)) {
//                            if (StrUtil.isNotEmpty(taskDto.getExt_task_id())) {
//                                JSONArray array = new JSONArray();
//                                JSONObject map = new JSONObject();
//                                map.put("task_id", taskDto.getExt_task_id());
//                                map.put("task_status", "1");
//                                array.add(map);
//                                acsToWmsService.feedbackTaskStatusToWms(array);
//                            }
//                        }
                        ;
                        //this.setNow_steps_type1(1);
                    }
                }
            }

            //单任务 后工位任务更新指令状态
            if (task2 > 0 && type == 2) {
                //inst_message
                Instruction inst2 = instructionService.findByCodeFromCache(String.valueOf(task2));
                if (inst2 != null) {
                    if (StrUtil.equals(inst2.getInstruction_status(), "0")) {
                        //当前指令更新状态
                        now_steps_type2 = 1;
                        inst2.setInstruction_status("1");
                        inst2.setExecute_device_code(this.device_code);
                        instructionService.update(inst2);
//                        TaskDto taskDto = taskserver.findByCodeFromCache(inst2.getTask_code());
//                        if (!ObjectUtil.isEmpty(taskDto)) {
//                            if (StrUtil.isNotEmpty(taskDto.getExt_task_id())) {
//                                JSONArray array = new JSONArray();
//                                JSONObject map = new JSONObject();
//                                map.put("task_id", taskDto.getExt_task_id());
//                                map.put("task_status", "1");
//                                array.add(map);
//                                acsToWmsService.feedbackTaskStatusToWms(array);
//                            }
//                        }
                        ;
                        // this.setNow_steps_type2(1);
                    }
                }
            }

            //双任务更新指令状态
            if (task2 > 0 && task1 > 0 && type == 3) {
                //inst_message
                Instruction inst2 = instructionService.findByCodeFromCache(String.valueOf(task1));
                if (inst2 != null) {
                    if (StrUtil.equals(inst2.getInstruction_status(), "0")) {
                        //当前指令更新状态
                        inst2.setInstruction_status("1");
                        inst2.setExecute_device_code(this.device_code);
                        instructionService.update(inst2);
//                        TaskDto taskDto = taskserver.findByCodeFromCache(inst2.getTask_code());
//                        if (!ObjectUtil.isEmpty(taskDto)) {
//                            if (StrUtil.isNotEmpty(taskDto.getExt_task_id())) {
//                                JSONArray array = new JSONArray();
//                                JSONObject map = new JSONObject();
//                                map.put("task_id", taskDto.getExt_task_id());
//                                map.put("task_status", "1");
//                                array.add(map);
//                                acsToWmsService.feedbackTaskStatusToWms(array);
//                            }
//                        }
                        ;
                    }
                }
            }

            //双任务/单任务 后工位取空时判断动作信号，并反馈
            if (mode == 3 && action2 == 1 && move2 == 0 && task2 > 0) {
                Instruction inst1 = instructionService.findByCodeFromCache(String.valueOf(task2));
                String start_device_code = inst1.getStart_device_code();
                Device startDevice = deviceAppservice.findDeviceByCode(start_device_code);
                if (ObjectUtil.isEmpty(startDevice)) {
                    feedMessage = "后工位取货位:" + start_device_code + "为空！";
                    logServer.deviceExecuteLog(this.getDeviceCode(), "", "", "后工位取货位:" + start_device_code + "为空！");
                    throw new BadRequestException("后工位取货位:" + start_device_code + "为空！");
                }
                SiemensConveyorDeviceDriver siemensConveyorDeviceDriver;
                if (startDevice.getDeviceDriver() instanceof SiemensConveyorDeviceDriver) {
                    siemensConveyorDeviceDriver = (SiemensConveyorDeviceDriver) startDevice.getDeviceDriver();
                    int move = siemensConveyorDeviceDriver.getMove();
                    int mode = siemensConveyorDeviceDriver.getMode();
                    if (mode == 2 && move == 1) {
                        this.writing("to_command2", "2");
                        if (type == 2) {
                            this.setNow_steps_type2(3);
                        } else if (type == 3) {
                            this.setNow_steps_type3(3);
                        }
                    } else {
                        log.warn("后工位取货位无货,取货位:{},mode:{},move:{}", start_device_code, mode, move);
                        if (this.getNow_steps_type2() == 2 || this.getNow_steps_type3() == 2) {
                            feedMessage = "后工位未取货原因-->";
                            if (mode != 2) {
                                feedMessage += "后工位取货位工作模式不为待机(mode != 2),";
                            } else if (move != 1) {
                                feedMessage += "后工位取货位无货(move != 1)";
                            }
                        }
                    }
                }
            } else {
                if (this.getNow_steps_type2() == 2 || this.getNow_steps_type3() == 2) {
                    feedMessage = "后工位未取货原因-->";
                    if (mode != 3) {
                        feedMessage += "行架工作模式不为运行中(mode != 3),";
                    }
                    if (action2 != 1) {
                        feedMessage += "后工位动作信号不为取货中(action2 != 1),";
                    }
                    if (move2 != 0) {
                        feedMessage += "后工位光电信号不为空(move2 != 0),";
                    }
                    if (task2 == 0) {
                        feedMessage += "后工位没有任务(task2 == 0)";
                    }
                }
            }

            //单任务/或双任务 后工位收到取货完成信号并反馈
            if (mode == 3 && action2 == 2 && move2 == 1 && task2 > 0) {
                this.writing("to_command2", "3");
                if (type == 2) {
                    this.setNow_steps_type2(4);
                }
                if (type == 3) {
                    this.setNow_steps_type3(4);
                }
            } else {
                if (this.getNow_steps_type2() == 3 || this.getNow_steps_type3() == 3) {
                    feedMessage = "后工位取货完成后未反馈原因-->";
                    if (mode != 3) {
                        feedMessage += "行架工作模式不为运行中(mode != 3),";
                    }
                    if (action2 != 2) {
                        feedMessage += "后工位未取货完成(action2 != 2),";
                    }
                    if (move2 == 0) {
                        feedMessage += "后工位光电信号为空(move2 == 0),";
                    }
                    if (task2 == 0) {
                        feedMessage += "后工位没有任务(task2 == 0)";
                    }
                }
            }

            //单任务/双任务 前工位取货时判断动作信号并反馈
            if (mode == 3 && action1 == 1 && move1 == 0 && task1 > 0) {
                this.writing("to_command1", "2");
                if (type == 1) {
                    this.setNow_steps_type1(3);
                } else if (type == 3) {
                    this.setNow_steps_type3(5);
                }
            } else {
                if (this.getNow_steps_type1() == 2 || this.getNow_steps_type3() == 4) {
                    feedMessage = "前工位未取货原因";
                    if (mode != 3) {
                        feedMessage += "行架工作模式不为运行中(mode != 3),";
                    }
                    if (action1 != 1) {
                        feedMessage += "前工位动作信号不为取货中(action2 != 1),";
                    }
                    if (move1 != 0) {
                        feedMessage += "前工位光电信号不为空(move2 != 0),";
                    }
                    if (task1 == 0) {
                        feedMessage += "前工位没有任务(task2 == 0)";
                    }
                }
            }

            //单任务/双任务 前工位取货完成并反馈
            if (mode == 3 && action1 == 2 && move1 == 1 && task1 > 0) {
                this.writing("to_command1", "3");
                if (type == 1) {
                    this.setNow_steps_type1(4);
                }
                if (type == 3) {
                    this.setNow_steps_type3(6);
                }
            } else {
                if (this.getNow_steps_type1() == 3 || this.getNow_steps_type3() == 5) {
                    feedMessage = "前工位取货完成后未反馈原因";
                    if (mode != 3) {
                        feedMessage += "行架工作模式不为运行中(mode != 3),";
                    }
                    if (action1 != 2) {
                        feedMessage += "前工位未取货完成(action2 != 2),";
                    }
                    if (move1 == 0) {
                        feedMessage += "前工位光电信号为空(move2 == 0),";
                    }
                    if (task1 == 0) {
                        feedMessage += "前工位没有任务(task2 == 0)";
                    }
                }
            }


            //单任务/双任务 后工位放货时判断信号并反馈
            if (mode == 3 && action2 == 3 && move2 == 1 && task2 > 0) {
                this.writing("to_command2", "4");
                if (type == 2) {
                    this.setNow_steps_type2(5);
                } else if (type == 3) {
                    this.setNow_steps_type3(7);
                }
            } else {
                if (this.getNow_steps_type2() == 4 || this.getNow_steps_type3() == 6) {
                    feedMessage = "后工位未放货原因-->";
                    if (mode != 3) {
                        feedMessage += "行架工作模式不为运行中(mode != 3),";
                    }
                    if (action2 != 3) {
                        feedMessage += "后工位动作信号不为放货中(action2 != 3),";
                    }
                    if (move2 == 0) {
                        feedMessage += "后工位光电信号为空(move2 == 0),";
                    }
                    if (task2 == 0) {
                        feedMessage += "后工位没有任务(task2 == 0)";
                    }
                }
            }

            //单任务 后工位放货完成 任务完成
            if (mode == 3 && action2 == 4 && move2 == 0 && task2 > 0 && type == 2) {
                //inst_message
                Instruction inst2 = instructionService.findByCodeFromCache(String.valueOf(task2));
                if (inst2 != null) {
                    if (StrUtil.equals(inst2.getInstruction_status(), "1")) {
                        finish_instruction(inst2);
                        TaskDto taskDto = taskserver.findByCodeFromCache(inst2.getTask_code());
                        if (!ObjectUtil.isEmpty(taskDto)) {
                            if (StrUtil.isNotEmpty(taskDto.getExt_task_id())) {
                                JSONArray array = new JSONArray();
                                JSONObject map = new JSONObject();
                                map.put("task_id", taskDto.getExt_task_id());
                                map.put("task_status", "2");
                                array.add(map);
                                acsToWmsService.feedbackTaskStatusToWms(array);
                            }
                        }
                        ;
                        this.writing("to_command2", "5");
                        this.setNow_steps_type2(6);
                        this.setNow_steps_type2(0);
                    }
                }
            } else {
                if (this.getNow_steps_type2() == 5) {
                    feedMessage = "单任务后工位放货完成后未反馈原因-->";
                    if (mode != 3) {
                        feedMessage += "行架工作模式不为运行中(mode != 3),";
                    }
                    if (action2 != 4) {
                        feedMessage += "后工位未放货完成(action2 != 4),";
                    }
                    if (move2 != 0) {
                        feedMessage += "后工位光电信号为有货(move2 != 0),";
                    }
                    if (task2 == 0) {
                        feedMessage += "后工位没有任务(task2 == 0),";
                    }
                    if (type != 2) {
                        feedMessage += "不是后工位单任务(type != 2)";
                    }
                }
            }

            //双任务 后工位反馈任务完成 并反馈
            if (mode == 3 && action2 == 4 && move2 == 0 && task1 > 0 && task2 > 0 && type == 3) {
                this.writing("to_command2", "5");
                this.setNow_steps_type3(8);
            } else {
                if (this.getNow_steps_type3() == 7) {
                    feedMessage = "双任务后工位放货完成后未反馈原因-->";
                    if (mode != 3) {
                        feedMessage += "行架工作模式不为运行中(mode != 3),";
                    }
                    if (action2 != 4) {
                        feedMessage += "后工位未放货完成(action2 != 4),";
                    }
                    if (move2 != 0) {
                        feedMessage += "后工位光电信号为有货(move2 != 0),";
                    }
                    if (task1 == 0) {
                        feedMessage += "前工位没有任务(task1 == 0),";
                    }
                    if (task2 == 0) {
                        feedMessage += "后工位没有任务(task2 == 0),";
                    }
                    if (type != 3) {
                        feedMessage += "不是双任务(type != 3)";
                    }
                }
            }

            //单任务/双任务 前工位放货时判断放货位光电信号
            if (mode == 3 && action1 == 3 && move1 == 1 && task1 > 0) {
                Instruction inst1 = instructionService.findByCodeFromCache(String.valueOf(task1));
                String next_device_code = "";
                if (type == 1) {
                    next_device_code = inst1.getNext_device_code();
                } else if (type == 3) {
                    next_device_code = inst1.getNext_device_code2();
                }
                Device nextDevice = deviceAppservice.findDeviceByCode(next_device_code);
                if (ObjectUtil.isEmpty(nextDevice)) {
                    feedMessage = "前工位放货位:" + next_device_code + "为空！";
                    throw new BadRequestException("前工位放货位:" + next_device_code + "为空！");
                }
                SiemensConveyorDeviceDriver siemensConveyorDeviceDriver;
                if (nextDevice.getDeviceDriver() instanceof SiemensConveyorDeviceDriver) {
                    siemensConveyorDeviceDriver = (SiemensConveyorDeviceDriver) nextDevice.getDeviceDriver();
                    int move = siemensConveyorDeviceDriver.getMove();
                    int mode = siemensConveyorDeviceDriver.getMode();
                    if (move == 1 && mode == 2) {
                        this.writing("to_command1", "4");
                        if (type == 1) {
                            this.setNow_steps_type1(5);
                        } else if (type == 3) {
                            this.setNow_steps_type3(9);
                        }
                    } else {
                        log.warn("后工位放货位有货,放货位:{},mode:{},move:{}", next_device_code, mode, move);
                        if (this.getNow_steps_type1() == 4 || this.getNow_steps_type3() == 8) {
                            feedMessage = "前工位未放货原因-->";
                            if (mode != 2) {
                                feedMessage += "前工位放货位工作模式不为待机(mode != 2),";
                            } else if (move == 0) {
                                feedMessage += "前工位放货位无货(move == 0)";
                            }
                        }
                    }
                }
            } else {
                if (this.getNow_steps_type1() == 4 || this.getNow_steps_type3() == 8) {
                    feedMessage = "前工位未放货原因-->";
                    if (mode != 3) {
                        feedMessage += "行架工作模式不为运行中(mode != 3),";
                    }
                    if (action1 != 3) {
                        feedMessage += "前工位动作信号不为放货中(action1 != 3),";
                    }
                    if (move1 == 0) {
                        feedMessage += "前工位光电信号为空(move1 == 0),";
                    }
                    if (task1 == 0) {
                        feedMessage += "前工位没有任务(task1 == 0),";
                    }
                }
            }


            //单任务前工位放货完成 任务完成
            if (mode == 3 && action1 == 4 && move1 == 0 && task1 > 0 && type == 1) {
                //inst_message
                Instruction inst1 = instructionService.findByCodeFromCache(String.valueOf(task1));
                if (inst1 != null) {
                    if (StrUtil.equals(inst1.getInstruction_status(), "1")) {
                        this.finish_instruction(inst1);
                        TaskDto taskDto = taskserver.findByCodeFromCache(inst1.getTask_code());
                        if (!ObjectUtil.isEmpty(taskDto)) {
                            if (StrUtil.isNotEmpty(taskDto.getExt_task_id())) {
                                JSONArray array = new JSONArray();
                                JSONObject map = new JSONObject();
                                map.put("task_id", taskDto.getExt_task_id());
                                map.put("task_status", "2");
                                array.add(map);
                                acsToWmsService.feedbackTaskStatusToWms(array);
                            }
                        }
                        ;
                        this.writing("to_command1", "5");
                        this.setNow_steps_type1(6);
                        this.setNow_steps_type1(0);
                    }
                }
            } else {
                if (this.getNow_steps_type1() == 5) {
                    feedMessage = "单任务前工位放货完成后未反馈原因-->";
                    if (mode != 3) {
                        feedMessage += "行架工作模式不为运行中(mode != 3),";
                    }
                    if (action1 != 4) {
                        feedMessage += "前工位未放货完成(action1 != 4),";
                    }
                    if (move1 != 0) {
                        feedMessage += "前工位光电信号为有货(move1 != 0),";
                    }
                    if (task1 == 0) {
                        feedMessage += "前工位没有任务(task1 == 0),";
                    }
                    if (type != 1) {
                        feedMessage += "不为前工位单任务(type != 1)";
                    }
                }
            }


            //双工位  任务完成 前工位反馈4
            if (mode == 3 && action1 == 4 && move1 == 0 && task1 > 0 && task2 > 0 && type == 3) {
                //inst_message
                Instruction inst1 = instructionService.findByCodeFromCache(String.valueOf(task1));
                if (inst1 != null) {
                    if (StrUtil.equals(inst1.getInstruction_status(), "1")) {
                        this.finish_instruction(inst1);
                        TaskDto taskDto = taskserver.findByCodeFromCache(inst1.getTask_code());
                        if (!ObjectUtil.isEmpty(taskDto)) {
                            if (StrUtil.isNotEmpty(taskDto.getExt_task_id())) {
                                JSONArray array = new JSONArray();
                                JSONObject map = new JSONObject();
                                map.put("task_id", taskDto.getExt_task_id());
                                map.put("task_status", "2");
                                array.add(map);
                                acsToWmsService.feedbackTaskStatusToWms(array);
                            }
                        }
                        ;
                        this.writing("to_command1", "5");
                        this.setNow_steps_type3(10);
                        this.setNow_steps_type3(0);
                    }
                }
            } else {
                if (this.getNow_steps_type3() == 9) {
                    feedMessage = "双任务前工位放货完成后未反馈原因-->";
                    if (mode != 3) {
                        feedMessage += "行架工作模式不为运行中(mode != 3),";
                    }
                    if (action1 != 4) {
                        feedMessage += "前工位未放货完成(action1 != 4),";
                    }
                    if (move1 != 0) {
                        feedMessage += "前工位光电信号为有货(move1 != 0),";
                    }
                    if (task1 == 0) {
                        feedMessage += "前工位没有任务(task1 == 0),";
                    }
                    if (task2 == 0) {
                        feedMessage += "后工位没有任务(task2 == 0),";
                    }
                    if (type != 3) {
                        feedMessage += "不是双任务(type != 3)";
                    }
                }
            }


        } catch (Exception var17) {
            feedMessage = var17.getMessage();
            logServer.deviceExecuteLog(this.device_code, "", "", "读取信号值时出现异常:" + var17.getMessage());
//            return;
        }

//        if (!this.itemProtocol.getIsonline()) {
//            this.setIsonline(false);
//            this.setIserror(true);
//            message = "信号量同步异常";
//            //未联机
//        } else
            if (mode == 0) {
            this.setIsonline(false);
            message = "未联机";
            //有报警
        } else if (error != 0) {
            this.setIserror(true);
            message = "有报警";
            //无报警
        } else {
            this.setIsonline(true);
            this.setIserror(false);
            switch (mode) {
                case 1:
                    log.debug("设备运转模式:等待工作");
                    return;
                case 2:
                    //申请任务
                    if (mode == 2 && move1 == 0 && move2 == 0 && action1 == 0 && action2 == 0 && task1 == 0 && task2 == 0 && !requireSucess) {
                        //获取关联设备驱动信息 判断关联设备是否禁用
                        String link_device_code = String.valueOf(this.getDevice().getExtraValue().get("link_device_code"));
                        Device device = deviceAppservice.findDeviceByCode(link_device_code);
                        SlitTwoManipulatorDeviceDriver slitTwoManipulatorDeviceDriver;
                        if (device.getDeviceDriver() instanceof SlitTwoManipulatorDeviceDriver) {
                            slitTwoManipulatorDeviceDriver = (SlitTwoManipulatorDeviceDriver) device.getDeviceDriver();
                            //如果禁用
                            if (slitTwoManipulatorDeviceDriver.getIs_disable() == 1) {
                                boolean flag = false;
                                try {
                                    //就去走关联设备异常取放货工位的任务 任务生成成功返回true 就不会走下面正常生成任务的逻辑
                                    flag = instruction_require2();
                                } catch (Exception e) {
                                    flag = false;
                                }
                                if (flag) {
                                    break;
                                }
                            }
                        }
                        //没有生成异常取放货工位的任务 就生成正常关联取放货工位的任务
                        instruction_require();
                        feedMessage = "";
                        notCreateInstMessage = "";
                        notCreateTaskMessage = "";
                        logServer.deviceExecuteLog(device_code, "", String.valueOf(task1), "move2:" + move2 + ",action2:" + action2 + ",move1:" + move1 + ",action1:" + action1 + ",requireSucess:" + requireSucess);
                    } else {
//                        if (!requireSucess) {
//                            remark = remark + "请求标记为true,请检查mode是否由其他值变为2！";
//                        }
                        if (!requireSucess) {
                            String remark = "";
                            if (mode != 2) {
                                remark = remark + "行架工作模式不为待机(mode != 2),";
                            }
                            if (move1 != 0) {
                                remark = remark + "前工位有货(move1 != 0),";
                            }
                            if (move2 != 0) {
                                remark = remark + "后工位有货(move2 != 0),";
                            }
                            if (action1 != 0) {
                                remark = remark + "前工位动作信号不为0(action1 != 0),";
                            }
                            if (action2 != 0) {
                                remark = remark + "后工位动作信号不为0(action2 != 0),";
                            }
                            if (task1 != 0) {
                                remark = remark + "前工位存在任务(task1 != 0),";
                            }
                            if (task2 != 0) {
                                remark = remark + "后工位存在任务(task2 != 0),";
                            }
                            this.setNotCreateTaskMessage(remark);
                        }
                    }
                    break;
                case 3:
                    break;
            }

        }
        last_mode = mode;
        last_error = error;
        last_status = status;
        last_move1 = move1;
        last_move2 = move2;
        last_action1 = action1;
        last_action2 = action2;
        last_walk_y = walk_y;
        last_type = type;
        last_task1 = task1;
        last_task2 = task2;
    }

    //关联设备异常申请任务
    public synchronized boolean instruction_require2() {
        Boolean flag = false;
        Date date = new Date();
        if (date.getTime() - this.instruction_head_time.getTime() < (long) this.instruction_require_time_out) {
            log.trace("触发时间因为小于{}毫秒，而被无视", this.instruction_head_time);
            return false;
        } else {
            this.instruction_head_time = date;
            //前工位取货关联设备
            List<String> getDeviceCodeList = this.getExtraDeviceCodes("error_head_get_device_code");
            //后工位取货关联设备
            List<String> backGetDeviceCodeList = this.getExtraDeviceCodes("error_back_get_device_code");
            TaskDto taskDto = null;
            //遍历前工位取货点设备
            for (String getDeviceCode : getDeviceCodeList) {
                //去任务表中查询是否有前工位关联设备的重新创建指令的任务
                List<TaskDto> taskDtos = taskserver.queryTaskByStartAndIntStatus(getDeviceCode);
                //如果有
                if (ObjectUtil.isNotEmpty(taskDtos)) {
                    //按照优先级排序 优先级相等按照创建时间排序
                    taskDtos = this.sortTask(taskDtos);
                    taskDto = taskDtos.get(0);
                    flag = this.executeBusiness(taskDto, getDeviceCodeList, backGetDeviceCodeList);
                    return flag;
                } else {
                    //去任务表中查询是否有前工位关联设备的就绪状态下的任务
                    taskDtos = taskserver.queryTaskByStartDeviceCode(getDeviceCode);
                    if (ObjectUtil.isNotEmpty(taskDtos)) {
                        //按照优先级排序 优先级相等按照创建时间排序
                        taskDtos = this.sortTask(taskDtos);
                        taskDto = taskDtos.get(0);
                        break;
                    }
                }
            }
            //如果任务表中起点1或起点2中 无前工位取货点关联设备
            //就去查询任务表中查找起点1或起点2为后工位取货点关联设备的任务
            if (ObjectUtil.isEmpty(taskDto)) {
                for (String backGetDeviceCode : backGetDeviceCodeList) {
                    //去任务表中查询是否有前工位关联设备的重新创建指令的任务
                    List<TaskDto> taskDtos = taskserver.queryTaskByNextAndIntStatus(backGetDeviceCode);
                    if (ObjectUtil.isNotEmpty(taskDtos)) {
                        //按照优先级排序 优先级相等按照创建时间排序
                        taskDtos = this.sortTask(taskDtos);
                        taskDto = taskDtos.get(0);
                        flag = this.executeBusiness(taskDto, getDeviceCodeList, backGetDeviceCodeList);
                        return flag;
                    } else {
                        //去任务表中查询是否有后工位关联设备的就绪状态下的任务
                        taskDtos = taskserver.queryTaskByBackDeviceCode(backGetDeviceCode);
                        if (ObjectUtil.isNotEmpty(taskDtos)) {
                            //按照优先级排序 优先级相等按照创建时间排序
                            taskDtos = this.sortTask(taskDtos);
                            taskDto = taskDtos.get(0);
                            break;
                        }
                    }
                }
            }
            if (!ObjectUtil.isEmpty(taskDto)) {
                flag = this.executeReadyBusiness(taskDto, getDeviceCodeList, backGetDeviceCodeList);
                if (flag) {
                    notCreateInstMessage = "";
                }
            } else {
                notCreateTaskMessage = "";
                notCreateInstMessage = "未找到关联设备禁用的任务!";
            }
        }
        return flag;
    }

    //正常申请任务
    public synchronized boolean instruction_require() {
        boolean flag = false;
        Date date = new Date();
        if (date.getTime() - this.instruction_head_time.getTime() < (long) this.instruction_require_time_out) {
            log.trace("触发时间因为小于{}毫秒，而被无视", this.instruction_head_time);
            return false;
        } else {
            this.instruction_head_time = date;
            //前工位取货关联设备
            List<String> getDeviceCodeList = this.getExtraDeviceCodes("head_get_device_code");
            //后工位取货关联设备
            List<String> backGetDeviceCodeList = this.getExtraDeviceCodes("back_get_device_code");
            TaskDto taskDto = null;
            //遍历前工位取货点设备
            for (String getDeviceCode : getDeviceCodeList) {
                //去任务表中查询是否有前工位关联设备的重新创建指令的任务
                List<TaskDto> taskDtos = taskserver.queryTaskByStartAndIntStatus(getDeviceCode);
                //如果有
                if (ObjectUtil.isNotEmpty(taskDtos)) {
                    //按照优先级排序 优先级相等按照创建时间排序
                    taskDtos = this.sortTask(taskDtos);
                    taskDto = taskDtos.get(0);
                    flag = this.executeBusiness(taskDto, getDeviceCodeList, backGetDeviceCodeList);
                    return flag;
                } else {
                    //去任务表中查询是否有前工位关联设备的就绪状态下的任务
                    taskDtos = taskserver.queryTaskByStartDeviceCode(getDeviceCode);
                    if (ObjectUtil.isNotEmpty(taskDtos)) {
                        //按照优先级排序 优先级相等按照创建时间排序
                        taskDtos = this.sortTask(taskDtos);
                        taskDto = taskDtos.get(0);
                        break;
                    }
                }
            }
            //如果任务表中起点1或起点2中 无前工位取货点关联设备
            //就去查询任务表中查找起点1或起点2为后工位取货点关联设备的任务
            if (ObjectUtil.isEmpty(taskDto)) {
                for (String backGetDeviceCode : backGetDeviceCodeList) {
                    //去任务表中查询是否有前工位关联设备的重新创建指令的任务
                    List<TaskDto> taskDtos = taskserver.queryTaskByNextAndIntStatus(backGetDeviceCode);
                    if (ObjectUtil.isNotEmpty(taskDtos)) {
                        //按照优先级排序 优先级相等按照创建时间排序
                        taskDtos = this.sortTask(taskDtos);
                        taskDto = taskDtos.get(0);
                        flag = this.executeBusiness(taskDto, getDeviceCodeList, backGetDeviceCodeList);
                        return flag;
                    } else {
                        //去任务表中查询是否有后工位关联设备的就绪状态下的任务
                        taskDtos = taskserver.queryTaskByBackDeviceCode(backGetDeviceCode);
                        if (ObjectUtil.isNotEmpty(taskDtos)) {
                            //按照优先级排序 优先级相等按照创建时间排序
                            taskDtos = this.sortTask(taskDtos);
                            taskDto = taskDtos.get(0);
                            break;
                        }
                    }
                }
            }

            if (!ObjectUtil.isEmpty(taskDto)) {
                flag = this.executeReadyBusiness(taskDto, getDeviceCodeList, backGetDeviceCodeList);
                if (flag) {
                    notCreateInstMessage = "";
                    notCreateTaskMessage = "";
                }
            } else {
                notCreateTaskMessage = "";
                notCreateInstMessage = "未找到正常关联设备的任务!";
            }
        }
        return flag;
    }

    //执行重新生成指令的任务
    public synchronized boolean executeBusiness(TaskDto taskDto, List<String> getDeviceCodeList, List<String> backGetDeviceCodeList) {
        boolean flag = false;
        //任务类型 1.前工位任务 2.后工位任务 3.双工位任务
        String type = "";
        //获取指令信息
        Instruction instructionDto = instructionService.findByTaskcodeAndStatus(taskDto.getTask_code());
        //获取指令表中的取货点1
        String start_device_code = instructionDto.getStart_device_code();
        //获取指令表中的取货点2
        String start_device_code2 = instructionDto.getStart_device_code2();
        //获取指令表中的放货点1
        String next_device_code = instructionDto.getNext_device_code();
        //获取指令表中的放货点2
        String next_device_code2 = instructionDto.getNext_device_code2();
        //判断任务点位是否配置电气信号
        Device startDevice = deviceAppservice.findDeviceByCode(start_device_code);
        Device startDevice2 = deviceAppservice.findDeviceByCode(start_device_code2);
        Device nextDevice = deviceAppservice.findDeviceByCode(next_device_code);
        Device nextDevice2 = deviceAppservice.findDeviceByCode(next_device_code2);
        //如果指令表中的取货点1和取货点2 都不为空 则说明时下双工位任务
        if (StrUtil.isNotEmpty(start_device_code2) && StrUtil.isNotEmpty(start_device_code)) {
            this.isSetAddress(startDevice);
            this.isSetAddress(nextDevice);
            this.isSetAddress(startDevice2);
            this.isSetAddress(nextDevice2);
            type = "3";
        } else {
            //判断指令表中的起点1 是否是前工位/后工位取货点的关联设备
            int headGetIndex = getDeviceCodeList.indexOf(start_device_code);
            int backGetIndex = backGetDeviceCodeList.indexOf(start_device_code);
            if (headGetIndex != -1) {
                //前工位
                type = "1";
            } else if (backGetIndex != -1) {
                //后工位
                type = "2";
            }
            this.isSetAddress(startDevice);
            this.isSetAddress(nextDevice);
        }

        //修改指令状态
        instructionDto.setInstruction_status("1");
        instructionDto.setUpdate_time(DateUtil.now());
        try {
            instructionService.update(instructionDto);
            if (StrUtil.equals(type, "1")) {
                this.setNow_steps_type1(1);
            }
            if (StrUtil.equals(type, "2")) {
                this.setNow_steps_type2(1);
            }
            if (StrUtil.equals(type, "3")) {
                this.setNow_steps_type3(1);
            }
            flag = true;
        } catch (Exception e) {
            logServer.deviceExecuteLog(device_code, "", instructionDto.getInstruction_code(), "执行重新生成指令的任务失败，原因->" + e.getMessage());
        }

        //下发电气信号
        this.sendSignalType(instructionDto, type);

        //请求任务成功
        requireSucess = true;
        return flag;
    }

    //执行就绪状态下的任务
    public synchronized boolean executeReadyBusiness(TaskDto taskDto, List<String> getDeviceCodeList, List<String> backGetDeviceCodeList) {
        boolean flag = false;
        //任务类型 1.前工位任务 2.后工位任务 3.双工位任务
        String type = "";
        //获取任务表中的取货点1
        String start_device_code = taskDto.getStart_device_code();
        //获取任务表中的取货点2
        String start_device_code2 = taskDto.getStart_device_code2();
        //获取任务表中的放货点1
        String next_device_code = taskDto.getNext_device_code();
        //获取任务表中的放货点2
        String next_device_code2 = taskDto.getNext_device_code2();
        //判断任务点位是否配置电气信号
        Device startDevice = deviceAppservice.findDeviceByCode(start_device_code);
        Device nextDevice = deviceAppservice.findDeviceByCode(next_device_code);
        Device startDevice2 = deviceAppservice.findDeviceByCode(start_device_code2);
        Device nextDevice2 = deviceAppservice.findDeviceByCode(next_device_code2);
        logServer.deviceExecuteLog(this.getDeviceCode(), "", "", "" +
                "执行就绪状态下的任务生成指令时:起点1为:" + start_device_code + "起点2为:" + start_device_code2 + ",任务信息为:" + taskDto.toString());
        //如果指令表中的取货点1和取货点2 都不为空 则说明时下双工位任务
        if (StrUtil.isNotEmpty(start_device_code2) && StrUtil.isNotEmpty(start_device_code)) {
            type = "3";
            logServer.deviceExecuteLog(this.getDeviceCode(), "", "", "" +
                    "执行就绪状态下的任务生成指令时:起点1为:" + start_device_code + "起点2为:" + start_device_code2 +
                    "type值为:" + type + ",任务信息为:" + taskDto.toString());
            //判断四个点位是否都设置电气值
            this.isSetAddress(startDevice);
            this.isSetAddress(nextDevice);
            this.isSetAddress(startDevice2);
            this.isSetAddress(nextDevice2);
        } else {
            //判断指令表中的起点1 是否是前工位/后工位取货点的关联设备
            int headGetIndex = getDeviceCodeList.indexOf(start_device_code);
            int backGetIndex = backGetDeviceCodeList.indexOf(start_device_code);
            if (headGetIndex != -1) {
                type = "1"; //前工位
            } else if (backGetIndex != -1) {
                type = "2"; //后工位
            }
            logServer.deviceExecuteLog(this.getDeviceCode(), "", "", "" +
                    "执行就绪状态下的任务生成指令时:起点1为:" + start_device_code + "起点2为:" + start_device_code2
                    + "type值为:" + type + ",任务信息为:" + taskDto.toString());
            //判断单任务下的两个点位是否都设置电气值
            this.isSetAddress(startDevice);
            this.isSetAddress(nextDevice);
        }

        String taskid = taskDto.getTask_id();
        String taskcode = taskDto.getTask_code();
        String vehiclecode = taskDto.getVehicle_code();
        String priority = taskDto.getPriority();
        String start_point_code = taskDto.getStart_point_code();
        String next_point_code = taskDto.getNext_point_code();
        String start_point_code2 = taskDto.getStart_point_code2();
        String next_point_code2 = taskDto.getNext_point_code2();
        String route_plan_code = taskDto.getRoute_plan_code();
        String remark = taskDto.getRemark();
        String material = taskDto.getMaterial();
        String quantity = taskDto.getQuantity();

        Instruction instdto = new Instruction();
        instdto.setInstruction_id(IdUtil.simpleUUID());
        instdto.setRoute_plan_code(route_plan_code);
        instdto.setRemark(remark);
        instdto.setMaterial(material);
        instdto.setQuantity(quantity);
        instdto.setTask_id(taskid);
        instdto.setTask_code(taskcode);
        instdto.setVehicle_code(vehiclecode);
        String now = DateUtil.now();
        instdto.setCreate_time(now);
        instdto.setCreate_by("auto");
        instdto.setStart_device_code(start_device_code);
        instdto.setNext_device_code(next_device_code);
        instdto.setStart_point_code(start_point_code);
        instdto.setNext_point_code(next_point_code);
        instdto.setPriority(priority);
        instdto.setInstruction_status("0");
        instdto.setExecute_device_code(start_point_code);
        instdto.setStart_device_code2(start_device_code2);
        instdto.setStart_point_code2(start_point_code2);
        instdto.setNext_device_code2(next_device_code2);
        instdto.setNext_point_code2(next_point_code2);

        try {
            logServer.deviceExecuteLog(this.getDeviceCode(), "", "", "" +
                    "执行就绪状态下的任务生成指令时:起点1为:" + start_device_code + "起点2为:" + start_device_code2
                    + "type值为:" + type + ",创建指令信息为:" + instdto.toString());
            instructionService.create(instdto);
            flag = true;
        } catch (Exception e) {
            notCreateInstMessage = e.getMessage();
            logServer.deviceExecuteLog(device_code, "", instdto.getInstruction_code(), "指令创建失败，原因->" + e.getMessage());
        }

        //创建指令后修改任务状态
        taskDto.setTask_status("1");
        taskDto.setUpdate_time(DateUtil.now());
        taskserver.update(taskDto);

        //下发电气信号
        this.sendSignalType(instdto, type);

        //请求任务成功
        requireSucess = true;
        return flag;
    }

    //下发电气信号
    public synchronized void sendSignalType(Instruction dto, String type) {
        logServer.deviceExecuteLog(this.getDeviceCode(), "", "", "开始下发电气信号,即下发电气指令信息为:"
                + dto.toString() + ",type = " + type);
        String start_device_code = dto.getStart_device_code();
        String next_device_code = dto.getNext_device_code();
        Device startDevice = deviceAppservice.findDeviceByCode(start_device_code);
        Device nextDevice = deviceAppservice.findDeviceByCode(next_device_code);
        String start_addr = startDevice.getExtraValue().get("address").toString();
        String next_addr = nextDevice.getExtraValue().get("address").toString();
        List list = new ArrayList();
        if (StrUtil.equals(type, "1")) {
            Map map1 = new HashMap();
            map1.put("code", "to_onset1");
            map1.put("value", start_addr);
            list.add(map1);
            Map map2 = new HashMap();
            map2.put("code", "to_target1");
            map2.put("value", next_addr);
            list.add(map2);
            Map map3 = new HashMap();
            map3.put("code", "to_task1");
            map3.put("value", dto.getInstruction_code());
            list.add(map3);
            Map map4 = new HashMap();
            map4.put("code", "to_type");
            map4.put("value", "1");
            list.add(map4);
            Map map5 = new HashMap();
            map5.put("code", "to_command1");
            map5.put("value", "1");
            list.add(map5);
            HashMap<String, String> map6 = new HashMap<String, String>() {{
                put("code", "to_command2");
                put("value", "0");
            }};
            list.add(map6);
            this.writing(list);
            logServer.deviceExecuteLog(device_code, "", "", dto.getInstruction_code() + "下发前工位任务");

//            this.writing("to_onset1", start_addr);
//            this.writing("to_target1", next_addr);
//            this.writing("to_task1", dto.getInstruction_code());
//            this.writing("to_command1", "1");
//            this.writing("to_type", "1");
            this.setNow_steps_type1(2);
        } else if (StrUtil.equals(type, "2")) {
            Map map1 = new HashMap();
            map1.put("code", "to_onset2");
            map1.put("value", start_addr);
            list.add(map1);
            Map map2 = new HashMap();
            map2.put("code", "to_target2");
            map2.put("value", next_addr);
            list.add(map2);
            Map map3 = new HashMap();
            map3.put("code", "to_task2");
            map3.put("value", dto.getInstruction_code());
            list.add(map3);
            Map map4 = new HashMap();
            map4.put("code", "to_type");
            map4.put("value", "2");
            list.add(map4);
            Map map5 = new HashMap();
            map5.put("code", "to_command2");
            map5.put("value", "1");
            list.add(map5);
            HashMap map6 = new HashMap() {{
                put("code", "to_command1");
                put("value", "0");
            }};
            list.add(map6);
            this.writing(list);
            logServer.deviceExecuteLog(device_code, "", "", dto.getInstruction_code() + "下发后工位任务");

//            this.writing("to_onset2", start_addr);
//            this.writing("to_target2", next_addr);
//            this.writing("to_task2", dto.getInstruction_code());
//            this.writing("to_command2", "1");
//            this.writing("to_type", "2");
            this.setNow_steps_type2(2);
        } else if (StrUtil.equals(type, "3")) {
            String start_device_code2 = dto.getStart_device_code2();
            String next_device_code2 = dto.getNext_device_code2();
            Device startDevice2 = deviceAppservice.findDeviceByCode(start_device_code2);
            Device nextDevice2 = deviceAppservice.findDeviceByCode(next_device_code2);
            String start_addr2 = startDevice2.getExtraValue().get("address").toString();
            String next_addr2 = nextDevice2.getExtraValue().get("address").toString();


            Map map1 = new HashMap();
            map1.put("code", "to_onset1");
            map1.put("value", start_addr2);
            list.add(map1);
            Map map2 = new HashMap();
            map2.put("code", "to_target1");
            map2.put("value", next_addr2);
            list.add(map2);
            Map map3 = new HashMap();
            map3.put("code", "to_task1");
            map3.put("value", dto.getInstruction_code());
            list.add(map3);
            Map map4 = new HashMap();
            map4.put("code", "to_onset2");
            map4.put("value", start_addr);
            list.add(map4);
            Map map5 = new HashMap();
            map5.put("code", "to_target2");
            map5.put("value", next_addr);
            list.add(map5);
            Map map6 = new HashMap();
            map6.put("code", "to_task2");
            map6.put("value", dto.getInstruction_code());
            list.add(map6);
            Map map7 = new HashMap();
            map7.put("code", "to_type");
            map7.put("value", "3");
            list.add(map7);
            Map map8 = new HashMap();
            map8.put("code", "to_command1");
            map8.put("value", "1");
            list.add(map8);
            Map map9 = new HashMap();
            map9.put("code", "to_command2");
            map9.put("value", "1");
            list.add(map9);
            this.writing(list);
            logServer.deviceExecuteLog(device_code, "", "", dto.getInstruction_code() + "下发双工位任务");


//            this.writing("to_onset1", start_addr2);
//            this.writing("to_target1", next_addr2);
//            this.writing("to_task1", dto.getInstruction_code());
//            this.writing("to_command1", "1");
//            this.writing("to_onset2", start_addr);
//            this.writing("to_target2", next_addr);
//            this.writing("to_task2", dto.getInstruction_code());
//            this.writing("to_command2", "1");
//            this.writing("to_type", "3");
            this.setNow_steps_type3(2);
        }

        if (task1 != Integer.parseInt(dto.getInstruction_code()) || task2 != Integer.parseInt(dto.getInstruction_code())) {
            this.writing(list);
            logServer.deviceExecuteLog(device_code, "", "", dto.getInstruction_code() + "再次下发电气信号");
        }

    }

    //判断点位是否设置电气值
    public void isSetAddress(Device device) {
        if (ObjectUtil.isEmpty(device.getExtraValue().get("address"))) {
            logServer.deviceExecuteLog(device_code, "", "task1:" + task1 + ",task2:" + task2, "设备：" + device.getDevice_code() + "未设置电气调度号！");
            notCreateInstMessage = "设备：" + device.getDevice_code() + "未设置电气调度号！";
            throw new BadRequestException("设备：" + device.getDevice_code() + "未设置电气调度号！");
        }
    }

    public boolean exe_error() {
        if (this.error == 0) {
            return true;
        } else {
            log.debug("设备报警");
            return false;
        }
    }

    public void writing(String param, String value) {
        String to_param = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code()
                + "." + param;
        //String opcservcerid = this.getDevice().getOpc_server_id();
//Server server = ReadUtil.getServer(opcservcerid);
        Map<String, Object> itemMap = new HashMap<String, Object>();
        itemMap.put(to_param, Integer.parseInt(value));

        this.control(itemMap);
        logServer.deviceExecuteLog(device_code, "", "", "下发电气信号设备号:" + device_code + ",下发电气:" + to_param + ",下发电气值:" + value);
    }

    public boolean exe_business() {
        return true;
    }

    protected void executing(Instruction instruction) {
        this.executing(1, instruction, "");
    }

    public void executing(int command, Instruction instruction, String appendMessage) {

        //String opcservcerid = this.getDevice().getOpc_server_id();
//Server server = ReadUtil.getServer(opcservcerid);
        Map<String, Object> itemMap = new HashMap<String, Object>();
        this.control(itemMap);

    }


    public synchronized boolean finish_instruction(Instruction inst) throws Exception {
        instructionService.finish(inst);
        return true;
    }


    public void executing(Server server, Map<String, Object> itemMap) {
        this.control(itemMap);
    }

    public void writing1(int command) {
        String to_command1 = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code()
                + "." + ItemProtocol.item_to_command1;

        //String opcservcerid = this.getDevice().getOpc_server_id();
//Server server = ReadUtil.getServer(opcservcerid);
        Map<String, Object> itemMap = new HashMap<String, Object>();
        itemMap.put(to_command1, command);
        this.control(itemMap);

    }

    public void writing2(int command) {
        String to_command2 = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code()
                + "." + ItemProtocol.item_to_command2;

        //String opcservcerid = this.getDevice().getOpc_server_id();
//Server server = ReadUtil.getServer(opcservcerid);
        Map<String, Object> itemMap = new HashMap<String, Object>();
        itemMap.put(to_command2, command);
        this.control(itemMap);

    }

    public void writing(int type, int command) {
        //String opcservcerid = this.getDevice().getOpc_server_id();
//Server server = ReadUtil.getServer(opcservcerid);
        Map<String, Object> itemMap = new HashMap<String, Object>();
        this.control(itemMap);
    }

    public void writing(List list) {

//        String opcservcerid = this.getDevice().getOpc_server_id();
//        Server server = ReadUtil.getServer(opcservcerid);
        Map<String, Object> itemMap = new HashMap<String, Object>();
        for (int i = 0; i < list.size(); i++) {
            Object ob = list.get(i);
            JSONObject json = (JSONObject) JSONObject.toJSON(ob);
            if (!StrUtil.isEmpty(json.getString("value"))) {
                String to_param = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code()
                        + "." + json.getString("code");
                itemMap.put(to_param, json.getString("value"));
            }
        }
        logServer.deviceExecuteLog(device_code, "", "", "下发电气信号:" + itemMap);
        this.control(itemMap);
    }


    //将扩展表中的字符串数组数据转换成集合
    public List<String> getExtraDeviceCodes(String extraName) {
        String extraValue = (String) this.getDevice().getExtraValue().get(extraName);
        if (StrUtil.isEmpty(extraValue)) {
            return new ArrayList<>();
        }
        String devicesString = extraValue.substring(1, extraValue.length() - 1);
        List<String> devicesList = new ArrayList<>();
        String[] devices = devicesString.split(",");
        for (int i = 0; i < devices.length; i++) {
            String s = devices[i].replace("\"", "").replace("\"", "");
            devicesList.add(s);
        }
        return devicesList;
    }

    public List<TaskDto> sortTask(List<TaskDto> taskDtos) {
        Collections.sort(taskDtos, new Comparator<TaskDto>() {
            @Override
            public int compare(TaskDto t1, TaskDto t2) {
                //优先级从大到小
                int i = t2.getPriority().compareTo(t1.getPriority());
                //如果优先级相等
                if (i == 0) {
                    //时间从早到晚
                    i = t1.getCreate_time().compareTo(t2.getCreate_time());
                }
                return i;
            }
        });
        return taskDtos;
    }

    @Override
    public JSONObject getDeviceStatusName() {
        JSONObject jo = new JSONObject();
        String move_1 = "";
        String move_2 = "";
        String action1 = "";
        String action2 = "";
        String walk_y = "";
        String mode = "";
        String status = "";
        String is_disable = "";


        if (this.getMode() == 0) {
            mode = "脱机";
        } else if (this.getMode() == 1) {
            mode = "单机";
        } else if (this.getMode() == 2) {
            mode = "待机";
        } else if (this.getMode() == 3) {
            mode = "运行中";
        }

        if (this.getStatus() == 0) {
            status = "0";
        } else if (this.getStatus() == 1) {
            status = "待机";
        } else if (this.getStatus() == 2) {
            status = "生产中";
        } else if (this.getStatus() == 3) {
            status = "故障";
        }

        if (this.getMove1() == 0) {
            move_1 = "无货";
        } else if (this.getMove1() == 1) {
            move_1 = "有货";
        }

        if (this.getMove2() == 0) {
            move_2 = "无货";
        } else if (this.getMove2() == 1) {
            move_2 = "有货";
        }

        if (this.getAction1() == 1) {
            action1 = "取货中";
        } else if (this.getAction1() == 2) {
            action1 = "取货完成";
        } else if (this.getAction1() == 3) {
            action1 = "放货中";
        } else if (this.getAction1() == 4) {
            action1 = "放货完成";
        }

        if (this.getAction2() == 1) {
            action2 = "取货中";
        } else if (this.getAction2() == 2) {
            action2 = "取货完成";
        } else if (this.getAction2() == 3) {
            action2 = "放货中";
        } else if (this.getAction2() == 4) {
            action2 = "放货完成";
        }

        if (this.getWalk_y() == 0) {
            walk_y = "原位";
        } else if (this.getWalk_y() == 2) {
            walk_y = "非原位";
        }

        if (this.getIs_disable() == 0) {
            is_disable = "正常";
        } else if (this.getIs_disable() == 1) {
            is_disable = "禁用";
        }

        String requireSucess = "0";
        if (this.requireSucess) {
            requireSucess = "1";
        }
        jo.put("requireSucess", requireSucess);

        jo.put("device_name", this.getDevice().getDevice_name());
        jo.put("mode", mode);
        jo.put("status", status);
        jo.put("move_1", move_1);
        jo.put("move_2", move_2);
        jo.put("action_1", action1);
        jo.put("action_2", action2);
        jo.put("walk_y", walk_y);
        jo.put("error", this.getError());
        jo.put("task1", this.getTask1());
        jo.put("task2", this.getTask2());
        jo.put("isOnline", this.getIsonline());
        jo.put("isError", this.getIserror());
        jo.put("is_disable1", this.getIs_disable());
        jo.put("is_disable", is_disable);
        jo.put("message", this.messageInfo(type));
        jo.put("is_click", true);
        jo.put("driver_type", "slit_two_manipulator");
        jo.put("notCreateTaskMessage", notCreateTaskMessage);
        jo.put("notCreateInstMessage", notCreateInstMessage);
        jo.put("feedMessage", feedMessage);
        return jo;
    }

    public String messageInfo(int type) {
        String set_type = "";
        JSONObject map = new JSONObject();
        if (type == 1) {
            set_type = String.valueOf(now_steps_type1);
            map.put("0", "前工位单任务未执行");
            map.put("1", "前工位单任务改变指令状态");
            map.put("2", "前工位单任务下发电气任务信息");
            map.put("3", "单任务前工位允许取货");
            map.put("4", "单任务前工位取货完成");
            map.put("5", "单任务前工位允许放货");
            map.put("6", "单任务前工位放货完成");
        } else if (type == 2) {
            set_type = String.valueOf(now_steps_type2);
            map.put("0", "后工位单任务未执行");
            map.put("1", "后工位单任务改变指令状态");
            map.put("2", "后工位单任务下发电气任务信息");
            map.put("3", "单任务后工位允许取货");
            map.put("4", "单任务后工位取货完成");
            map.put("5", "单任务后工位允许放货");
            map.put("6", "单任务后工位放货完成");
        } else if (type == 3) {
            set_type = String.valueOf(now_steps_type3);
            map.put("0", "双任务未执行");
            map.put("1", "双任务改变指令状态");
            map.put("2", "双任务下发电气任务信息");
            map.put("3", "双任务后工位允许取货");
            map.put("4", "双任务后工位取货完成");
            map.put("5", "双任务前工位允许取货");
            map.put("6", "双任务前工位取货完成");
            map.put("7", "双任务后工位允许放货");
            map.put("8", "双任务后工位放货完成");
            map.put("9", "双任务前工位允许放货");
            map.put("10", "双任务前工位放货完成");
        } else {
            return "未执行任务";
        }
        return map.getString(set_type);
    }

    @Override
    public void setDeviceStatus(JSONObject data) {
        String is_disable = data.getString("is_disable");
        if (StrUtil.isNotEmpty(is_disable)) {
            this.setIs_disable(Integer.parseInt(is_disable));
        }
        String requestSucess = data.getString("requireSucess");
        if (StrUtil.equals(requestSucess, "0")) {
            this.requireSucess = false;
        } else if (StrUtil.equals(requestSucess, "1")) {
            this.requireSucess = true;
        }
    }
}
