package org.nl.acs.device_driver.basedriver.oven_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.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.hongxiang_device.HongXiangConveyorDeviceDriver;
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 OvenGantryManipulatorDeviceDriver 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
    DeviceExecuteLogService logServer = SpringContextHolder.getBean("deviceExecuteLogServiceImpl");
    @Autowired
    AcsToWmsService acsToWmsService = SpringContextHolder.getBean("acsToWmsServiceImpl");
    @Autowired
    DeviceAppService deviceAppService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);

    //工作模式
    int mode = 0;
    int last_mode = 0;
    //光电信号
    int move = 0;
    int last_move = 0;
    //动作信号
    int action = 0;
    int last_action = 0;
    //行走列
    int walk_y = 0;
    int last_walk_y = 0;
    //报警信号
    int error = 0;
    int last_error = 0;
    //任务号
    int task = 0;
    int last_task = 0;


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

    Integer heartbeat_tag;
    private Date instruction_require_time = new Date();

    private int instruction_require_time_out;
    //行架机械手申请任务成功标识
    boolean requireSucess = false;

    private int instruction_finished_time_out;

    int branchProtocol = 0;


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

    String device_code;

    //0 无任务执行 1更新指令状态 2下发电气信号 3允许取货 允许放货 5放货完成
    int now_steps_type = 0;
    String notCreateTaskMessage = "";
    String notCreateInstMessage = "";
    String feedMessage = "";


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


    @Override
    public void execute() {
        String message = null;
        try {
            device_code = this.getDeviceCode();
            mode = this.itemProtocol.getMode();
            move = this.itemProtocol.getMove();
            action = this.itemProtocol.getAction();
            walk_y = this.itemProtocol.getWalk_y();
            error = this.itemProtocol.getError();
            task = this.itemProtocol.getTask();
            if (mode != last_mode) {
                if (mode == 2) {
                    logServer.deviceExecuteLog(this.device_code, "", "", "信号复位前requireSuccess：" + requireSucess);
                    this.setRequireSucess(false);
                    message = null;
                    logServer.deviceExecuteLog(this.device_code, "", "", "信号复位后requireSuccess：" + requireSucess);
                }
                logServer.deviceItemValue(this.device_code, "mode", String.valueOf(mode));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号mode：" + last_mode + "->" + mode);
            }
            if (move != last_move) {
                logServer.deviceItemValue(this.device_code, "move", String.valueOf(move));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号move：" + last_move + "->" + move);
            }
            if (action != last_action) {
                logServer.deviceItemValue(this.device_code, "action", String.valueOf(action));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号action：" + last_action + "->" + action);
            }
            if (error != last_error) {
                logServer.deviceItemValue(this.device_code, "error", String.valueOf(error));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号error：" + last_error + "->" + error);
            }
            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 (task != last_task) {
                logServer.deviceItemValue(this.device_code, "task", String.valueOf(task));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号task：" + last_task + "->" + task);
            }

            //更改任务状态
            if (task > 0) {
                //inst_message
                Instruction inst1 = instructionService.findByCodeFromCache(String.valueOf(task));
                if (inst1 != null) {
                    if (StrUtil.equals(inst1.getInstruction_status(), "0")) {
                        inst1.setInstruction_status("1");
                        inst1.setExecute_device_code(this.device_code);
                        instructionService.update(inst1);
//                        TaskDto tas未反馈电气信号原因kDto = taskserver.findByCodeFromCache(inst1.getTask_code());
//                        if (ObjectUtil.isNotEmpty(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 && action == 1 && move == 0 && task > 0) {
                Instruction inst2 = instructionService.findByCodeFromCache(String.valueOf(task));
                if (ObjectUtil.isNotEmpty(inst2)) {
                    String start_device_code = inst2.getStart_device_code();
                    Device device = deviceAppService.findDeviceByCode(start_device_code);
                    HongXiangConveyorDeviceDriver hongXiangConveyorDeviceDriver;
                    if (device.getDeviceDriver() instanceof HongXiangConveyorDeviceDriver) {
                        hongXiangConveyorDeviceDriver = (HongXiangConveyorDeviceDriver) device.getDeviceDriver();
                        //hongXiangConveyorDeviceDriver.writing("to_open_door", "1");
                        int mode = hongXiangConveyorDeviceDriver.getMode();
                        int door = hongXiangConveyorDeviceDriver.getDoor();
                        int action = hongXiangConveyorDeviceDriver.getAction();
                        int error1 = hongXiangConveyorDeviceDriver.getError1();
                        if (mode == 1 && door == 1 && action == 1 && error1 == 0) {
                            if (this.getNow_steps_type() == 2) {
                                this.writing("to_command", "2");
                                this.setNow_steps_type(3);
                            } else {
                                logServer.deviceExecuteLog(this.device_code, "", "", "未反馈电气信号原因:当前步骤不为下发电气信号（now_steps_type！=2）");
                            }
                        } else {
                            if (this.getNow_steps_type() == 2) {
                                feedMessage = "烘箱:" + hongXiangConveyorDeviceDriver.getDevice_code();
                                if (mode != 1) {
                                    feedMessage = feedMessage + "mode未联机,";
                                }
                                if (door != 1) {
                                    feedMessage = feedMessage + "door未开门,";
                                }
                                if (action != 1) {
                                    feedMessage = feedMessage + "action未允许取放,";
                                }
                                if (error1 != 0) {
                                    feedMessage = feedMessage + "error1出现故障。";
                                }
                            }
                        }
                    } else {
                        if (this.getNow_steps_type() == 2) {
                            this.writing("to_command", "2");
                            this.setNow_steps_type(3);
                        } else {
                            logServer.deviceExecuteLog(this.device_code, "", "", "未反馈电气信号原因:当前步骤不为下发电气信号（now_steps_type！=2）\")");
                        }
                    }
                }
            } else {
                if (this.getNow_steps_type() == 2) {
                    feedMessage = "行架机械手:";
                    if (mode != 3) {
                        feedMessage = feedMessage + "mode不为运行中状态,";
                    }
                    if (action != 1) {
                        feedMessage = feedMessage + "action不为取货中状态,";
                    }
                    if (move != 0) {
                        feedMessage = feedMessage + "move不为无货状态,";
                    }
                    if (task == 0) {
                        feedMessage = feedMessage + "task为0。";
                    }
                }
            }

            //取货完成关闭烘箱门
            if (mode == 3 && action == 2 && move == 1 && task > 0) {
                Instruction inst2 = instructionService.findByCodeFromCache(String.valueOf(task));
                if (ObjectUtil.isNotEmpty(inst2)) {
                    String start_device_code = inst2.getStart_device_code();
                    Device device = deviceAppService.findDeviceByCode(start_device_code);
                    HongXiangConveyorDeviceDriver hongXiangConveyorDeviceDriver;
                    if (device.getDeviceDriver() instanceof HongXiangConveyorDeviceDriver) {
                        hongXiangConveyorDeviceDriver = (HongXiangConveyorDeviceDriver) device.getDeviceDriver();
                        hongXiangConveyorDeviceDriver.writing("to_close_door", "1");
                    }
                    if (this.getNow_steps_type() == 3) {
                        this.writing("to_command", "3");
                        this.setNow_steps_type(4);
                    } else {
                        logServer.deviceExecuteLog(this.device_code, "", "", "未反馈电气信号原因:当前步骤不为允许取货（now_steps_type！=3）");
                    }
                }
            } else {
                if (this.getNow_steps_type() == 3) {
                    feedMessage = "行架机械手:";
                    if (mode != 3) {
                        feedMessage = feedMessage + "mode不为运行中状态,";
                    }
                    if (action != 2) {
                        feedMessage = feedMessage + "action不为取货完成状态,";
                    }
                    if (move != 1) {
                        feedMessage = feedMessage + "move不为有货状态,";
                    }
                    if (task == 0) {
                        feedMessage = feedMessage + "task为0。";
                    }
                }
            }

            //申请放货
            if (mode == 3 && action == 3 && move == 1 && task > 0) {
                Instruction instructionDto = instructionService.findByCode(String.valueOf(task));
                String next_device_code = instructionDto.getNext_device_code();
                Device nextDevice = deviceAppService.findDeviceByCode(next_device_code);
                HongXiangConveyorDeviceDriver hongXiangConveyorDeviceDriver;
                if (nextDevice.getDeviceDriver() instanceof HongXiangConveyorDeviceDriver) {
                    hongXiangConveyorDeviceDriver = (HongXiangConveyorDeviceDriver) nextDevice.getDeviceDriver();
                    //hongXiangConveyorDeviceDriver.writing("to_open_door", "1");
                    int mode = hongXiangConveyorDeviceDriver.getMode();
                    int door = hongXiangConveyorDeviceDriver.getDoor();
                    int action = hongXiangConveyorDeviceDriver.getAction();
                    int error1 = hongXiangConveyorDeviceDriver.getError1();
                    if (mode == 1 && door == 1 && action == 1 && error1 == 0) {
                        if (this.getNow_steps_type() == 4) {
                            this.writing("to_command", "4");
                            this.setNow_steps_type(5);
                        } else {
                            logServer.deviceExecuteLog(this.device_code, "", "", "未反馈电气信号原因:当前步骤不为允许放货（now_steps_type！=4）");
                        }
                    } else {
                        feedMessage = "烘箱:" + hongXiangConveyorDeviceDriver.getDevice_code();
                        if (mode != 1) {
                            feedMessage = feedMessage + "mode未联机,";
                        }
                        if (door != 1) {
                            feedMessage = feedMessage + "door未开门,";
                        }
                        if (action != 1) {
                            feedMessage = feedMessage + "action未允许取放,";
                        }
                        if (error1 != 0) {
                            feedMessage = feedMessage + "error1出现故障。";
                        }
                    }
                } else {
                    if (this.getNow_steps_type() == 4) {
                        this.writing("to_command", "4");
                        this.setNow_steps_type(5);
                    } else {
                        logServer.deviceExecuteLog(this.device_code, "", "", "未反馈电气信号原因:当前步骤不为允许放货（now_steps_type！=4）");
                    }
                }
            } else {
                if (this.getNow_steps_type() == 4) {
                    feedMessage = "行架机械手:";
                    if (mode != 3) {
                        feedMessage = feedMessage + "mode不为运行中状态,";
                    }
                    if (action != 3) {
                        feedMessage = feedMessage + "action不为放货中状态,";
                    }
                    if (move != 1) {
                        feedMessage = feedMessage + "move不为有货状态,";
                    }
                    if (task == 0) {
                        feedMessage = feedMessage + "task为0。";
                    }
                }
            }

            //放货完成
            if (mode == 3 && action == 4 && move == 0 && task > 0) {
                Instruction inst2 = instructionService.findByCodeFromCache(String.valueOf(task));
                if (inst2 != null) {
                    if (StrUtil.equals(inst2.getInstruction_status(), "1")) {
                        try {
                            finish_instruction(inst2);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        TaskDto taskDto = taskserver.findByCode(inst2.getTask_code());

                        String next_device_code = taskDto.getNext_device_code();
                        //String start_device_code = taskDto.getStart_device_code();
                        //Device startDevice = deviceAppService.findDeviceByCode(start_device_code);
                        Device nextDevice = deviceAppService.findDeviceByCode(next_device_code);
                        HongXiangConveyorDeviceDriver hongXiangConveyorDeviceDriver;
//                        if (startDevice.getDeviceDriver() instanceof HongXiangConveyorDeviceDriver) {
//                            hongXiangConveyorDeviceDriver = (HongXiangConveyorDeviceDriver) startDevice.getDeviceDriver();
//                            hongXiangConveyorDeviceDriver.writing("to_close_door", "1");
//                        }
                        if (nextDevice.getDeviceDriver() instanceof HongXiangConveyorDeviceDriver) {
                            hongXiangConveyorDeviceDriver = (HongXiangConveyorDeviceDriver) nextDevice.getDeviceDriver();
                            hongXiangConveyorDeviceDriver.writing("to_close_door", "1");
                            if (StrUtil.isNotEmpty(taskDto.getOven_time())) {
                                //下发烘箱时间
                                int time = Integer.parseInt(taskDto.getOven_time());
                                int hours = (time % (60 * 60 * 24)) / (60 * 60);
                                int minutes = (time % (60 * 60)) / 60;
                                hongXiangConveyorDeviceDriver.writing("to_time_house", String.valueOf(hours));
                                hongXiangConveyorDeviceDriver.writing("to_time_min", String.valueOf(minutes));
                            }
                        }
                        if (this.getNow_steps_type() == 5) {
                            this.writing("to_command", "5");
                            this.setNow_steps_type(6);
                            this.setNow_steps_type(0);
                            feedMessage = "";
                        } else {
                            logServer.deviceExecuteLog(this.device_code, "", "", "未反馈电气信号原因:当前步骤不为放货完成（now_steps_type！=5）");
                        }
//                        this.writing("to_onset", "0");
//                        this.writing("to_target", "0");
//                        this.writing("to_task", "0");
                    }
                }
            } else {
                if (this.getNow_steps_type() == 5) {
                    feedMessage = "行架机械手:";
                    if (mode != 3) {
                        feedMessage = feedMessage + "mode不为运行中状态,";
                    }
                    if (action != 4) {
                        feedMessage = feedMessage + "action不为放货完成状态,";
                    }
                    if (move != 0) {
                        feedMessage = feedMessage + "move不为无货状态,";
                    }
                    if (task == 0) {
                        feedMessage = feedMessage + "task为0。";
                    }
                }
            }

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

//        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);
            message = "";
            Instruction instruction = null;
            List toInstructions;

            //行架机械手申请任务
            if (mode == 2 && move == 0 && task == 0 && !requireSucess) {
                applyTask();
                notCreateInstMessage = "";
                notCreateTaskMessage = "";
                feedMessage = "";
            } else {
                if (mode == 2) {
                    //if (!requireSucess) {
                    String remark = "未查找任务原因为:";
                    if (mode != 2) {
                        remark = remark + "mode不是待机状态,";
                    }
                    if (move != 0) {
                        remark = remark + "move为有货状态,";
                    }
                    if (task != 0) {
                        remark = remark + "task任务号不为0,";
                    }
                    if (requireSucess) {
                        remark = remark + "请求标记requireSucess为true。";
                    }
                    this.setNotCreateTaskMessage(remark);
                    //}
                }
            }

        }
        last_mode = mode;
        last_move = move;
        last_action = action;
        last_walk_y = walk_y;
        last_error = error;
        last_task = task;
    }


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


    /**
     * 申请任务
     *
     * @param
     */
    public synchronized boolean applyTask() {
        Date date = new Date();
        if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) {
            log.trace("触发时间因为小于{}毫秒，而被无视", this.instruction_require_time_out);
            return false;
        } else {
            this.instruction_require_time = date;
            //抓取工位
            List<String> getDeviceCodeList = this.getExtraDeviceCodes("get_device_code");
            //放货工位
            List<String> putDeviceCodeList = this.getExtraDeviceCodes("put_device_code");
            TaskDto task = null;
            for (int i = 0; i < getDeviceCodeList.size(); i++) {
                String startDeviceCode = getDeviceCodeList.get(i);
                List<TaskDto> taskDtos = taskserver.queryTaskByDeviceCodeAndStatus(startDeviceCode);
                if (ObjectUtil.isNotEmpty(taskDtos)) {
                    //按照优先级排序 优先级相等按照创建时间排序
                    taskDtos = this.sortTask(taskDtos);
                    TaskDto taskDto = taskDtos.get(0);
                    Instruction instruction = instructionService.findByTaskcode(taskDto.getTask_code());
                    String start_device_code = instruction.getStart_device_code();
                    String next_device_code = instruction.getNext_device_code();
                    //判断关联的同一列烘箱设备是否都关门 都关门返回false，有一个不关门就返回true
                    boolean isCloseDoor = this.judgeCloseDoor(start_device_code, next_device_code);
                    //未关门结束
                    if (isCloseDoor) {
                        return false;
                    }
                    instruction.setInstruction_status("1");
                    instruction.setUpdate_time(DateUtil.now());
                    instructionService.update(instruction);
                    Device startDevice = deviceAppService.findDeviceByCode(start_device_code);
                    Device nextDevice = deviceAppService.findDeviceByCode(next_device_code);
                    if (ObjectUtil.isEmpty(startDevice.getExtraValue().get("address"))) {
                        throw new BadRequestException("设备：" + startDevice.getDevice_code() + "未设置电气调度号！");
                    }
                    if (ObjectUtil.isEmpty(nextDevice.getExtraValue().get("address"))) {
                        throw new BadRequestException("设备：" + nextDevice.getDevice_code() + "未设置电气调度号！");
                    }
                    String start_addr = startDevice.getExtraValue().get("address").toString();
                    String next_addr = nextDevice.getExtraValue().get("address").toString();
                    this.writing("to_onset", start_addr);
                    this.writing("to_target", next_addr);
                    this.writing("to_task", instruction.getInstruction_code());
                    this.writing("to_command", "1");

                    this.setNow_steps_type(2);
                    this.setRequireSucess(true);
                    return true;
                } else {
                    List<TaskDto> taskDtoList = taskserver.queryTaskByDeviceCode(startDeviceCode);
                    if (ObjectUtil.isNotEmpty(taskDtoList)) {
                        //按照优先级排序 优先级相等按照创建时间排序
                        taskDtoList = this.sortTask(taskDtoList);
                        task = taskDtoList.get(0);
                    }
                    if (ObjectUtil.isNotEmpty(task)) break;
                }
            }
            if (!ObjectUtil.isEmpty(task)) {
                String taskid = task.getTask_id();
                String taskcode = task.getTask_code();
                String vehiclecode = task.getVehicle_code();
                String priority = task.getPriority();
                String start_point_code = task.getStart_point_code();
                String start_device_code = task.getStart_device_code();
                String route_plan_code = task.getRoute_plan_code();
                String next_point_code = task.getNext_point_code();
                String next_device_code = task.getNext_device_code();

                Instruction instdto = new Instruction();
                instdto.setInstruction_id(IdUtil.simpleUUID());
                instdto.setRoute_plan_code(route_plan_code);
                instdto.setRemark(task.getRemark());
                instdto.setMaterial(task.getMaterial());
                instdto.setQuantity(task.getQuantity());
                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);

                //判断关联的同一列烘箱设备是否都关门 都关门返回false，有一个不关门就返回true
                boolean isCloseDoor = this.judgeCloseDoor(instdto.getStart_device_code(), instdto.getNext_device_code());
                //如果未关门结束
                if (isCloseDoor) {
                    return false;
                }

                try {
                    instructionService.create(instdto);
                } catch (Exception e) {
                    notCreateInstMessage = e.getMessage();
                    logServer.deviceExecuteLog(this.getDevice_code(), "", "", "创建指令时出现异常:" + e.getMessage());
                    return false;
                }
                //创建指令后修改任务状态
                task.setTask_status("1");
                task.setUpdate_time(DateUtil.now());
                taskserver.update(task);

                Device startDevice = deviceAppService.findDeviceByCode(instdto.getStart_device_code());
                Device nextDevice = deviceAppService.findDeviceByCode(instdto.getNext_device_code());
                if (ObjectUtil.isEmpty(startDevice.getExtraValue().get("address"))) {
                    notCreateInstMessage = "设备：" + startDevice.getDevice_code() + "未设置电气调度号！";
                    logServer.deviceExecuteLog(this.getDevice_code(), "", "", "设备：" + startDevice.getDevice_code() + "未设置电气调度号！");
                    throw new BadRequestException("设备：" + startDevice.getDevice_code() + "未设置电气调度号！");
                }
                if (ObjectUtil.isEmpty(nextDevice.getExtraValue().get("address"))) {
                    notCreateInstMessage = "设备：" + nextDevice.getDevice_code() + "未设置电气调度号！";
                    logServer.deviceExecuteLog(this.getDevice_code(), "", "", "设备：" + nextDevice.getDevice_code() + "未设置电气调度号！");
                    throw new BadRequestException("设备：" + nextDevice.getDevice_code() + "未设置电气调度号！");
                }
                String start_addr = startDevice.getExtraValue().get("address").toString();
                String next_addr = nextDevice.getExtraValue().get("address").toString();
                this.writing("to_onset", start_addr);
                this.writing("to_target", next_addr);
                this.writing("to_task", instdto.getInstruction_code());
                this.writing("to_command", "1");
                HongXiangConveyorDeviceDriver hongXiangConveyorDeviceDriver;
                if (nextDevice.getDeviceDriver() instanceof HongXiangConveyorDeviceDriver) {
                    hongXiangConveyorDeviceDriver = (HongXiangConveyorDeviceDriver) nextDevice.getDeviceDriver();
                    hongXiangConveyorDeviceDriver.writing("to_open_door", "1");
                    hongXiangConveyorDeviceDriver.writing("to_open_door", "1");
                }
                if (startDevice.getDeviceDriver() instanceof HongXiangConveyorDeviceDriver) {
                    hongXiangConveyorDeviceDriver = (HongXiangConveyorDeviceDriver) startDevice.getDeviceDriver();
                    hongXiangConveyorDeviceDriver.writing("to_open_door", "1");
                    hongXiangConveyorDeviceDriver.writing("to_open_door", "1");
                }
                this.setNow_steps_type(2);
                this.setRequireSucess(true);
                notCreateInstMessage = "";
                notCreateTaskMessage = "";
            } else {
                notCreateInstMessage = "未找到关联设备的任务，指令无法创建";
            }
            return true;
        }
    }

    public boolean exe_business() {
        return true;
    }

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

    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));
//            itemMap.put(to_param, Integer.parseInt(value));
        this.control(itemMap);
        logServer.deviceExecuteLog(device_code, "", "", "下发电气信号设备号:" + device_code + ",下发电气:" + to_param + ",下发电气值:" + value);
    }

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

    //判断取货位或放货位为烘箱设备时关联的同一列烘箱设备是否有开门
    public boolean judgeCloseDoor(String start_device_code, String next_device_code) {
        Boolean isClose = false;

        try {
            Device startDevice = deviceAppService.findDeviceByCode(start_device_code);
            Device nextDevice = deviceAppService.findDeviceByCode(next_device_code);
            HongXiangConveyorDeviceDriver hongXiangConveyorDeviceDriver;
            if (ObjectUtil.isEmpty(startDevice)) {
                throw new BadRequestException("设备号:" + start_device_code + "不存在！");
            }
            if (startDevice.getDeviceDriver() instanceof HongXiangConveyorDeviceDriver) {
                hongXiangConveyorDeviceDriver = (HongXiangConveyorDeviceDriver) startDevice.getDeviceDriver();
                List<String> deviceCodes = hongXiangConveyorDeviceDriver.getExtraDeviceCodes("link_device_code");
                if (ObjectUtil.isNotEmpty(deviceCodes)) {
                    for (String deviceCode : deviceCodes) {
                        Device linkDevice = deviceAppService.findDeviceByCode(deviceCode);
                        if (ObjectUtil.isEmpty(linkDevice)) {
                            throw new BadRequestException("设备:" + start_device_code + "关联设备->" + deviceCode + "为空！");
                        }
                        if (linkDevice.getDeviceDriver() instanceof HongXiangConveyorDeviceDriver) {
                            hongXiangConveyorDeviceDriver = (HongXiangConveyorDeviceDriver) linkDevice.getDeviceDriver();
                            //判断关联设备是否开门
                            if (hongXiangConveyorDeviceDriver.getDoor() == 1) {
                                isClose = true;
                                notCreateInstMessage = start_device_code + "关联设备->" + deviceCode + "烘箱门未关闭！";
                                break;
                            }
                        }
                    }
                    return isClose;
                }
            }
            if (ObjectUtil.isEmpty(nextDevice)) {
                throw new BadRequestException("设备号:" + next_device_code + "不存在！");
            }
            if (nextDevice.getDeviceDriver() instanceof HongXiangConveyorDeviceDriver) {
                hongXiangConveyorDeviceDriver = (HongXiangConveyorDeviceDriver) nextDevice.getDeviceDriver();
                List<String> deviceCodes = hongXiangConveyorDeviceDriver.getExtraDeviceCodes("link_device_code");
                if (ObjectUtil.isNotEmpty(deviceCodes)) {
                    for (String deviceCode : deviceCodes) {
                        Device linkDevice = deviceAppService.findDeviceByCode(deviceCode);
                        if (ObjectUtil.isEmpty(linkDevice)) {
                            throw new BadRequestException("设备:" + next_device_code + "关联设备->" + deviceCode + "为空！");
                        }
                        if (linkDevice.getDeviceDriver() instanceof HongXiangConveyorDeviceDriver) {
                            hongXiangConveyorDeviceDriver = (HongXiangConveyorDeviceDriver) linkDevice.getDeviceDriver();
                            //判断关联设备是否开门
                            if (hongXiangConveyorDeviceDriver.getDoor() == 1) {
                                isClose = true;
                                notCreateInstMessage = next_device_code + "关联设备->" + deviceCode + "烘箱门未关闭！";
                                break;
                            }
                        }
                    }
                    return isClose;
                }
            }
        } catch (Exception e) {
            isClose = true;
            logServer.deviceExecuteLog(this.getDevice_code(), "", "", "检查烘箱是否关门时出现异常:" + e.getMessage());
            notCreateInstMessage = "检查烘箱是否关门时出现异常:" + e.getMessage();
        }
        return isClose;
    }

    public void writing(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 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 mode = "";
        String move = "";
        String action = "";
        String walk_y = "";
        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.getMove() == 0) {
            move = "无货";
        } else if (this.getMove() == 1) {
            move = "有货";
        }

        String requireSucess = "0";
        if (this.requireSucess) {
            requireSucess = "1";
        }
        jo.put("requireSucess", requireSucess);
        if (this.getAction() == 1) {
            action = "取货中";
        } else if (this.getAction() == 2) {
            action = "取货完成";
        } else if (this.getAction() == 3) {
            action = "放货中";
        } else if (this.getAction() == 4) {
            action = "放货完成";
        }

        jo.put("device_name", this.getDevice().getDevice_name());
        jo.put("mode", mode);
        jo.put("move", move);
        jo.put("action", action);
        jo.put("task", task);
        jo.put("walk_y", walk_y);
        jo.put("isOnline", this.getIsonline());
        jo.put("error", this.getError());
        jo.put("isError", this.getIserror());
        jo.put("message", this.getMessage());
        jo.put("notCreateTaskMessage", notCreateTaskMessage);
        jo.put("notCreateInstMessage", notCreateInstMessage);
        jo.put("feedMessage", feedMessage);
        jo.put("driver_type", "siemens_conveyor");
        jo.put("is_click", true);
        return jo;
    }

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

//    public void writing(int type, int command) {
//        String to_material_code = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code()
//                + "." + ItemProtocol.item_to_material_code;
//        String opcservcerid = this.getDevice().getOpc_server_id();
//        Server server = ReadUtil.getServer(opcservcerid);
//        Map<String, Object> itemMap = new HashMap<String, Object>();
//        if (type == 2) {
//            itemMap.put(to_material_code, command);
//        }
//        this.control(itemMap);
//
//    }

}
