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

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.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.nl.acs.AcsConfig;
import org.nl.acs.agv.server.NDCAgvService;
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.driver.AbstractOpcDeviceDriver;
import org.nl.acs.device_driver.driver.ExecutableDeviceDriver;
import org.nl.acs.ext.wms.data.ApplyLabelingAndBindingRequest;
import org.nl.acs.ext.wms.data.ApplyLabelingAndBindingResponse;
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.route.service.RouteLineService;
import org.nl.acs.route.service.dto.RouteLineDto;
import org.nl.acs.storage_cell.domain.StorageCell;
import org.nl.acs.storage_cell.service.mapper.StorageCellMapper;
import org.nl.acs.task.service.TaskService;
import org.nl.acs.task.service.dto.TaskDto;
import org.nl.system.service.param.ISysParamService;
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 SiemensConveyorLabelingDeviceDriver extends AbstractOpcDeviceDriver
    implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver, DeviceStageMonitor {
  protected ItemProtocol itemProtocol = new ItemProtocol(this);

  @Autowired
  InstructionService instructionService = SpringContextHolder.getBean(InstructionService.class);

  @Autowired DeviceService deviceservice = SpringContextHolder.getBean(DeviceService.class);
  @Autowired RouteLineService routelineserver = SpringContextHolder.getBean(RouteLineService.class);
  @Autowired TaskService taskserver = SpringContextHolder.getBean(TaskService.class);

  @Autowired
  DeviceAppService deviceAppservice = SpringContextHolder.getBean(DeviceAppService.class);

  @Autowired
  RouteLineService routeLineService = SpringContextHolder.getBean(RouteLineService.class);

  @Autowired ISysParamService paramService = SpringContextHolder.getBean(ISysParamService.class);
  @Autowired AcsToWmsService acsToWmsService = SpringContextHolder.getBean(AcsToWmsService.class);

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

  @Autowired NDCAgvService agvService = SpringContextHolder.getBean(NDCAgvService.class);

  @Autowired
  StorageCellMapper storageCellMapper;
  // 当前指令
  Instruction inst = null;

  // 工作模式
  int mode = 0;
  int last_mode = 0;
  // 光电信号
  int move = 0;
  int last_move = 0;
  // 托盘方向
  int carrier_direction = 0;
  int last_carrier_direction = 0;
  // 报警信号
  int error = 0;
  int last_error = 0;
  // 任务号
  int task = 0;
  int weight = 0;
  int last_task = 0;
  int agvphase = 0;

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

  Integer heartbeat_tag;
  private Date instruction_require_time = new Date();
  private Date require_apply_labeling_time = new Date();
  private Date require_apply_strangulation_time = new Date();
  private Date require_empty_in_time = new Date();
  private Date require_empty_out_time = new Date();

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

  int branchProtocol = 0;
  String inst_message;

  // 当前指令

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

  String device_code;

  String vehicle_code;

  @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();
      carrier_direction = this.itemProtocol.getCarrier_direction();
      error = this.itemProtocol.getError();
      task = this.itemProtocol.getTask();
      weight = this.itemProtocol.getWeight();
      if (mode != last_mode) {
        if (mode == 2) {
          requireSucess = false;
          requireApplyLabelingSuccess = false;
          requireApplyLaStrangulationSuccess = false;
          requireEmptyInSuccess = false;
          requireEmptyOutSuccess = false;
          logServer.deviceExecuteLog(this.device_code, "", "", "复位请求标记成功！");
        }
        logServer.deviceItemValue(this.device_code, "mode", String.valueOf(mode));
        logServer.deviceExecuteLog(this.device_code, "", "", "信号mode：" + last_mode + "->" + mode);
      }
      if (move != last_move) {
        if (move == 0 && mode == 2) {
          this.clearWrite();
        }
        logServer.deviceItemValue(this.device_code, "move", String.valueOf(move));
        logServer.deviceExecuteLog(this.device_code, "", "", "信号move：" + last_move + "->" + move);
      }
      if (carrier_direction != last_carrier_direction) {
        logServer.deviceItemValue(
            this.device_code, "carrier_direction", String.valueOf(carrier_direction));
        logServer.deviceExecuteLog(
            this.device_code,
            "",
            "",
            "信号carrier_direction：" + last_carrier_direction + "->" + carrier_direction);
      }
      if (error != last_error) {
        logServer.deviceItemValue(this.device_code, "error", String.valueOf(error));
        logServer.deviceExecuteLog(
            this.device_code, "", "", "信号error：" + last_error + "->" + error);
      }
      if (task != last_task) {
        logServer.deviceItemValue(this.device_code, "task", String.valueOf(task));
        logServer.deviceExecuteLog(this.device_code, "", "", "信号task：" + last_task + "->" + task);
      }

      if (mode == 2 && move != 0 && task > 0) {
        logServer.deviceExecuteLog(device_code, "", "", "入库输送线任务开始反馈任务状态,指令号:" + task);
        // inst_message
        inst = instructionService.findByCodeFromCache(String.valueOf(task));
        if (inst != null) {
          inst_message =
              "指令号:"
                  + inst.getInstruction_code()
                  + " "
                  + inst.getStart_point_code()
                  + "->"
                  + inst.getNext_point_code()
                  + "  载具号："
                  + inst.getVehicle_code();
          if (StrUtil.equals(inst.getInstruction_status(), "1")
              && StrUtil.equals(this.getDeviceCode(), inst.getNext_device_code())) {
            vehicle_code = inst.getVehicle_code();
            finish_instruction();
            logServer.deviceExecuteLog(device_code, "", "", "入库输送线任务开始反馈完成状态,反馈成功,指令号:" + task);
          } else if (StrUtil.equals(inst.getInstruction_status(), "0")
              && StrUtil.equals(this.getDeviceCode(), inst.getStart_device_code())) {
            inst.setInstruction_status("1");
            instructionService.update(inst);
            logServer.deviceExecuteLog(device_code, "", "", "入库输送线任务开始反馈执行中状态,反馈成功,指令号:" + task);
          } else {
            logServer.deviceExecuteLog(
                device_code, "", "", "入库输送线任务开始反馈执行中状态,反馈失败任务状态不为就绪或者执行中状态,指令号:" + task);
          }
        } else {
          logServer.deviceExecuteLog(device_code, "", "", "入库输送线任务开始反馈任务状态,反馈失败,查询不到指令号:" + task);
        }
      }

    } catch (Exception var17) {
      inst_message = var17.getMessage();
      logServer.deviceExecuteLog(this.getDevice_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.setIsonline(false);
      //            this.setIserror(true);
      //            message = "有报警";
      //            //无报警
    } else {
      this.setIsonline(true);
      this.setIserror(false);
      if (error != 0) {
        this.setIserror(true);
        message = "有报警";
      }
      message = "";
      Instruction instruction = null;
      List toInstructions;

      switch (mode) {
        case 1:
          log.debug("设备运转模式:等待工作");
          break;
        case 2:
          // 申请任务
          if (move > 0 && !requireSucess) {
            instruction_require();
          }
          break;
        case 4:
          // 申请捆扎
          if (move > 0 && !requireSucess) {
            applyLaStrangulation();
          }
          break;
        case 5:
          // 申请贴标
          if (move > 0 && !requireSucess) {
            applyLabeling();
          }
          break;
        case 6:
          // 空托盘满垛入库申请
          if (move > 0 && !requireEmptyInSuccess) {
            emptyIn();
          }
          if (move > 0 && !requireSucess) {
            instruction_require();
          }
          break;
        case 7:
          // 空盘出库申请
          if (move == 0 && !requireEmptyOutSuccess) {
            emptyOut();
          }
          break;
        case 8:
          // 申请AGV任务
          if (move == 0 && !requireSucess) {
            applyAgvTask();
          }
          break;
      }
    }
    last_mode = mode;
    last_move = move;
    last_carrier_direction = carrier_direction;
    last_error = error;
    last_task = task;
  }

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

  public void clearWrite() {

    List list = new ArrayList();
    Map map = new HashMap();
    map.put("code", "to_target");
    map.put("value", "0");
    list.add(map);
    Map map2 = new HashMap();
    map2.put("code", "to_task");
    map2.put("value", "0");
    list.add(map2);
    Map map3 = new HashMap();
    map3.put("code", "to_command");
    map3.put("value", "0");
    list.add(map3);
    Map map4 = new HashMap();
    map4.put("code", "to_strap_times");
    map4.put("value", "0");
    list.add(map4);
    Map map5 = new HashMap();
    map5.put("code", "to_length");
    map5.put("value", "0");
    list.add(map5);
    Map map6 = new HashMap();
    map6.put("code", "to_weight");
    map6.put("value", "0");
    list.add(map6);
    Map map7 = new HashMap();
    map7.put("code", "to_height");
    map7.put("value", "0");
    list.add(map7);
    this.writing(list);
    message = null;
    vehicle_code = null;
  }

  public boolean exe_business() {
    return true;
  }

  public synchronized boolean finish_instruction() throws Exception {
    instructionService.finish(inst);
    //        requireSucess = false;
    return true;
  }

  protected void thingToNothing() throws Exception {
    requireSucess = 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));
    //            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 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);
  }

  @Override
  public JSONObject getDeviceStatusName() {
    JSONObject jo = new JSONObject();
    String mode = "";
    String move = "";
    String carrier_direction = "";
    if (this.getMode() == 0) {
      mode = "脱机";
    } else if (this.getMode() == 1) {
      mode = "单机";
    } else if (this.getMode() == 2) {
      mode = "待机";
    } else if (this.getMode() == 3) {
      mode = "运行中";
    } else if (this.getMode() == 4) {
      mode = "申请捆扎中";
    } else if (this.getMode() == 5) {
      mode = "申请贴标中";
    } else if (this.getMode() == 6) {
      mode = "申请空盘入库中";
    } else if (this.getMode() == 7) {
      mode = "申请空盘出库中";
    } else if (this.getMode() == 8) {
      mode = "申请AGV任务中";
    }

    if (this.getMove() == 0) {
      move = "无货";
      jo.put("hasGoods", false);
    } else if (this.getMove() == 1) {
      move = "有货";
      jo.put("hasGoods", true);
    } else if (this.getMove() == 2) {
      move = "有托盘有货";
      jo.put("hasGoods", true);
    }
    String requireApplyLabelingSuccess = "0";
    if (this.requireApplyLabelingSuccess) {
      requireApplyLabelingSuccess = "1";
    }
    String requireApplyLaStrangulationSuccess = "0";
    if (this.requireApplyLaStrangulationSuccess) {
      requireApplyLaStrangulationSuccess = "1";
    }
    jo.put("requireApplyLabelingSuccess", requireApplyLabelingSuccess);
    jo.put("requireApplyLaStrangulationSuccess", requireApplyLaStrangulationSuccess);

    if (this.carrier_direction == 1) {
      carrier_direction = "正转";
    } else if (this.carrier_direction == 2) {
      carrier_direction = "反转";
    }
    String requireSucess = "0";
    if (this.requireSucess) {
      requireSucess = "1";
    }

    jo.put("device_name", this.getDevice().getDevice_name());
    jo.put("mode", mode);
    jo.put("move", move);
    jo.put("carrier_direction", carrier_direction);
    jo.put("task", task);
    jo.put("isOnline", this.getIsonline());
    jo.put("error", this.getError());
    jo.put("isError", this.getIserror());
    jo.put("message", this.getMessage());
    jo.put("is_click", true);
    jo.put("requireSucess", requireSucess);
    jo.put("driver_type", "siemens_conveyor");
    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(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 synchronized boolean instruction_require() {
    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;
      // 判断是否存在起点相同 任务状态就绪的任务
      TaskDto taskdto = taskserver.findByStartCodeAndReady(device_code);
      if (!ObjectUtil.isEmpty(taskdto)) {
        //                if
        // (!ObjectUtils.isEmpty(instructionService.findByBarcodeFromCache(container_code))) {
        //                    return false;
        //                }
        // 需要判断当前设备是否已经存在就绪的指令  如果存在就直接下发  不存在则创建
        Instruction inst = instructionService.findByTaskcodeAndStatus(taskdto.getTask_code());
        if (ObjectUtil.isNotEmpty(inst)) {
          List list = new ArrayList();
          Map map = new HashMap();

          if (StrUtil.isNotEmpty(taskdto.getTo_z())) {
            if (StrUtil.equals(taskdto.getTo_z(), "01")) {
              map.put("code", "to_target");
              map.put("value", "102");
            } else if (StrUtil.equals(taskdto.getTo_z(), "02")) {
              map.put("code", "to_target");
              map.put("value", "201");
            } else if (StrUtil.equals(taskdto.getTo_z(), "03")) {
              map.put("code", "to_target");
              map.put("value", "301");
            }
          }
          list.add(map);
          Map map2 = new HashMap();
          map2.put("code", "to_task");
          map2.put("value", inst.getInstruction_code());
          list.add(map2);
          Map map3 = new HashMap();
          map3.put("code", "to_command");
          map3.put("value", "1");
          list.add(map3);
          this.writing(list);
          if (task != Integer.parseInt(inst.getInstruction_code())) {
            this.writing(list);
            logServer.deviceExecuteLog(
                device_code, "", "", inst.getInstruction_code() + "再次下发电气信号");
          }
          message = "下发电气任务号成功";
          requireSucess = true;
          return true;
        }

        // type 5 输送任务
        if (!StrUtil.equals(taskdto.getTask_type(), "5")) {
          return false;
        }
        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 start_device_code = taskdto.getStart_device_code();
        String route_plan_code = taskdto.getRoute_plan_code();
        String next_device_code = "";

        /** 开始平均分配 */
        String this_coevice_code =
            taskserver.queryAssignedByDevice(device_code, taskdto.getNext_device_code());
        if (StrUtil.isEmpty(this_coevice_code)) {
          List<RouteLineDto> shortPathsList =
              routeLineService.getShortPathLines(
                  start_device_code, taskdto.getNext_device_code(), route_plan_code);
          RouteLineDto routeLineDto = shortPathsList.get(0);

          String path = routeLineDto.getPath();
          String type = routeLineDto.getType();
          String[] str = path.split("->");

          List<String> pathlist = Arrays.asList(str);
          int index = 0;
          for (int m = 0; m < pathlist.size(); m++) {
            if (pathlist.get(m).equals(start_device_code)) {
              index = m + 1;
              break;
            }
          }
          next_device_code = pathlist.get(index);
        } else {
          next_device_code = this_coevice_code;
        }
        // 校验路由关系
        List<RouteLineDto> shortPathsList =
            routeLineService.getShortPathLines(
                start_device_code, next_device_code, route_plan_code);
        if (ObjectUtils.isEmpty(shortPathsList)) {
          throw new RuntimeException("路由不通!");
        }

        Device startdevice = deviceAppservice.findDeviceByCode(start_device_code);
        Device nextdevice = deviceAppservice.findDeviceByCode(next_device_code);
        String next_point_code;
        if (StrUtil.equals(deviceAppservice.findDeviceTypeByCode(next_device_code), "storage")) {
          next_point_code = taskdto.getTo_x() + "-" + taskdto.getTo_y() + "-" + taskdto.getTo_z();
        } else {
          next_point_code = next_device_code;
        }
        Instruction instdto = new Instruction();
        instdto.setInstruction_id(IdUtil.simpleUUID());
        instdto.setRoute_plan_code(route_plan_code);
        instdto.setRemark(taskdto.getRemark());
        instdto.setMaterial(taskdto.getMaterial());
        instdto.setQuantity(taskdto.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);
        try {
          instructionService.create(instdto);
        } catch (Exception e) {
          e.printStackTrace();
          log.error("指令创建异常!");
          return false;
        }
        // 创建指令后修改任务状态
        taskdto.setTask_status("1");
        taskserver.update(taskdto);
        requireSucess = true;
        String next_addr = nextdevice.getExtraValue().get("address").toString();

        List list = new ArrayList();
        Map map = new HashMap();
        map.put("code", "to_target");
        map.put("value", next_addr);
        list.add(map);
        Map map2 = new HashMap();
        map2.put("code", "to_task");
        map2.put("value", instdto.getInstruction_code());
        list.add(map2);
        Map map3 = new HashMap();
        map3.put("code", "to_command");
        map3.put("value", "1");
        list.add(map3);
        this.writing(list);
        if (task != Integer.parseInt(inst.getInstruction_code())) {
          this.writing(list);
          logServer.deviceExecuteLog(device_code, "", "", inst.getInstruction_code() + "再次下发电气信号");
        }
      } else {
        // 如果不存在则直接找对应指令
        Instruction inst = instructionService.findByDeviceCodeFromCache(this.device_code);
        if (ObjectUtil.isEmpty(inst)) {
          return false;
        }
        // 当起点为行架任务的时候不需要请求下发
        if (StrUtil.equals(inst.getInstruction_type(), "6")) {
          return false;
        }
        Device nextdevice = deviceAppservice.findDeviceByCode(inst.getNext_device_code());
        String next_addr = nextdevice.getExtraValue().get("address").toString();

        List list = new ArrayList();
        Map map = new HashMap();
        map.put("code", "to_target");
        map.put("value", next_addr);
        list.add(map);
        Map map2 = new HashMap();
        map2.put("code", "to_task");
        map2.put("value", inst.getInstruction_code());
        list.add(map2);
        Map map3 = new HashMap();
        map3.put("code", "to_command");
        map3.put("value", "1");
        list.add(map3);
        this.writing(list);
        if (task != Integer.parseInt(inst.getInstruction_code())) {
          this.writing(list);
          logServer.deviceExecuteLog(device_code, "", "", inst.getInstruction_code() + "再次下发电气信号");
        }
      }
      return true;
    }
  }

  // 申请贴标
  public synchronized void applyLabeling() {
    Date date = new Date();
    if (date.getTime() - this.require_apply_labeling_time.getTime()
        < (long) this.instruction_require_time_out) {
      log.trace("触发时间因为小于{}毫秒，而被无视", this.instruction_require_time_out);
      return;
    } else {
      this.require_apply_labeling_time = date;
      String vehicle_code = "";
      if (weight == 0) {
        logServer.deviceExecuteLog(device_code, "", "", "申请贴标电气设备重量:" + weight + "异常");
        message = "申请贴标电气设备重量:" + weight + "异常";
        throw new RuntimeException("重量为空!");
      }
      if (task > 0) {
        Instruction instruction = instructionService.findByCodeFromCache(String.valueOf(task));
        if (ObjectUtil.isEmpty(instruction)) {
          instruction = instructionService.findByCode(String.valueOf(task));
        }
        vehicle_code = instruction.getVehicle_code();
      } else {
        logServer.deviceExecuteLog(device_code, "", "", "申请贴标电气设备任务号:" + task + "异常");
        message = "申请贴标电气设备任务号:" + task + "异常";
        throw new RuntimeException("任务号为空!");
      }
      if (StrUtil.isEmpty(vehicle_code)) {
        logServer.deviceExecuteLog(device_code, "", "", "申请贴标电气设备任务号:" + task + "未找到载具号");
        message = "申请贴标电气设备任务号:" + task + "未找到载具号";
        throw new RuntimeException("载具号为空!");
      }
      ApplyLabelingAndBindingRequest applyLabelingAndBindingRequest =
          new ApplyLabelingAndBindingRequest();
//      JSONObject device_json =
//          WQLObject.getWQLObject("acs_storage_cell")
//              .query("storage_code ='" + this.device_code + "'")
//              .uniqueResult(0);

      StorageCell storageCell = new LambdaQueryChainWrapper<>(storageCellMapper).eq(StorageCell::getStorage_code,this.device_code).one();
      String start_point_code = null;
      if (!ObjectUtil.isEmpty(storageCell)) {
        start_point_code =
            (String) storageCell.getParent_storage_code() == null
                ? this.device_code
                : (String) storageCell.getParent_storage_code();
      }
      applyLabelingAndBindingRequest.setDevice_code(start_point_code);
      applyLabelingAndBindingRequest.setType("1");
      applyLabelingAndBindingRequest.setVehicle_code(vehicle_code);
      applyLabelingAndBindingRequest.setWeight(String.valueOf((float) weight / 100));
      ApplyLabelingAndBindingResponse applyLabelingAndBindingResponse =
          acsToWmsService.applyLabelingAndBindingRequest(applyLabelingAndBindingRequest);

      if (applyLabelingAndBindingResponse.getstatus() == 200) {
        message = "申请贴标成功";
        List list = new ArrayList();
        Map map = new HashMap();
        map.put("code", "to_command");
        map.put("value", "5");
        list.add(map);
        this.writing(list);
        this.writing(list);
        message = "申请贴标下发电气信号成功";
        requireSucess = true;
      } else {
        message = "申请贴标失败," + applyLabelingAndBindingResponse.getMessage();
      }
    }
  }

  // 申请捆扎
  public synchronized void applyLaStrangulation() {
    Date date = new Date();
    if (date.getTime() - this.require_apply_strangulation_time.getTime()
        < (long) this.instruction_require_time_out) {
      log.trace("触发时间因为小于{}毫秒，而被无视", this.instruction_require_time_out);
      return;
    } else {
      this.require_apply_strangulation_time = date;
      String vehicle_code = "";
      if (task > 0) {
        Instruction instruction = instructionService.findByCodeFromCache(String.valueOf(task));
        vehicle_code = instruction.getVehicle_code();
      } else {
        logServer.deviceExecuteLog(device_code, "", "", "申请捆扎电气设备任务号:" + task + "异常");
        message = "申请捆扎电气设备任务号:" + task + "异常";
        throw new RuntimeException("任务号为空!");
      }
      if (StrUtil.isEmpty(vehicle_code)) {
        logServer.deviceExecuteLog(device_code, "", "", "申请捆扎电气设备任务号:" + task + "未找到载具号");
        message = "申请捆扎电气设备任务号:" + task + "未找到载具号";
        throw new RuntimeException("载具号为空!");
      }
      ApplyLabelingAndBindingRequest applyLabelingAndBindingRequest =
          new ApplyLabelingAndBindingRequest();
//      JSONObject device_json =
//          WQLObject.getWQLObject("acs_storage_cell")
//              .query("storage_code ='" + this.device_code + "'")
//              .uniqueResult(0);
      StorageCell storageCell = new LambdaQueryChainWrapper<>(storageCellMapper).eq(StorageCell::getStorage_code,this.device_code).one();
      String start_point_code = null;
      if (!ObjectUtil.isEmpty(storageCell)) {
        start_point_code =
            (String) storageCell.getParent_storage_code() == null
                ? this.device_code
                : (String) storageCell.getParent_storage_code();
      }
      applyLabelingAndBindingRequest.setDevice_code(start_point_code);
      applyLabelingAndBindingRequest.setType("2");
      applyLabelingAndBindingRequest.setVehicle_code(vehicle_code);
      ApplyLabelingAndBindingResponse applyLabelingAndBindingResponse =
          acsToWmsService.applyLabelingAndBindingRequest(applyLabelingAndBindingRequest);
      if (applyLabelingAndBindingResponse.getstatus() == 200) {
        if (ObjectUtil.isNotEmpty(applyLabelingAndBindingResponse.getData())) {
          Map datas = applyLabelingAndBindingResponse.getData();
          String length = datas.get("box_length").toString();
          String width = datas.get("box_width").toString();
          String box_high = datas.get("box_high").toString();
          String bundle_times = datas.get("bundle_times").toString();

          List list = new ArrayList();
          Map map = new HashMap();
          map.put("code", "to_length");
          map.put("value", length);
          list.add(map);
          Map map2 = new HashMap();
          map2.put("code", "to_weight");
          map2.put("value", width);
          list.add(map2);
          Map map3 = new HashMap();
          map3.put("code", "to_height");
          map3.put("value", box_high);
          list.add(map3);
          Map map4 = new HashMap();
          map4.put("code", "to_strap_times");
          map4.put("value", bundle_times);
          list.add(map4);
          Map map5 = new HashMap();
          map5.put("code", "to_command");
          map5.put("value", "4");
          list.add(map5);
          this.writing(list);
          this.writing(list);
          message = "申请贴标成功";
          requireSucess = true;
        } else {
          message = "未返回尺寸信息";
        }

      } else {
        message = applyLabelingAndBindingResponse.getMessage();
      }
    }
  }

  public synchronized void emptyIn() {
    Date date = new Date();
    if (date.getTime() - this.require_empty_in_time.getTime()
        < (long) this.instruction_require_time_out) {
      log.trace("触发时间因为小于{}毫秒，而被无视", this.instruction_require_time_out);
      return;
    } else {
      this.require_empty_in_time = date;

      if (StrUtil.equals(paramService.findByCode(AcsConfig.HASWMS).getValue(), "1")) {
        message = "申请空盘入库任务中...";
        JSONObject apply = new JSONObject();
        apply.put("device_code", device_code);
        apply.put("type", "2");
        String str = acsToWmsService.applyTaskToWms(apply);
        JSONObject jo = JSON.parseObject(str);
        if (ObjectUtil.isEmpty(jo)) {
          message = "申请空盘入库接口不通";
        } else {
          if (jo.getInteger("status") == 200) {
            message = "申请空盘入库成功";
            requireEmptyInSuccess = true;
          } else {
            requireEmptyInSuccess = false;
            message = "申请空盘入库失败，" + jo.get("message").toString();
          }
        }
      }
    }
  }

  public synchronized void applyAgvTask() {
    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;
    } else {
      this.instruction_require_time = date;
      if (StrUtil.equals(paramService.findByCode(AcsConfig.HASWMS).getValue(), "1")) {
        message = "申请AGV搬运任务中...";
        JSONObject apply = new JSONObject();
        apply.put("device_code", device_code);
        apply.put("type", "1");
        String str = acsToWmsService.applyTaskToWms(apply);
        JSONObject jo = JSON.parseObject(str);
        if (ObjectUtil.isEmpty(jo)) {
          message = "申请AGV搬运任务接口不通";
        } else {
          if (jo.getInteger("status") == 200) {
            message = "申请AGV搬运任务成功";
            requireEmptyOutSuccess = true;
          } else {
            requireEmptyOutSuccess = false;
            message = "申请AGV搬运任务失败," + jo.get("message").toString();
          }
        }
      }
    }
  }

  public synchronized void emptyOut() {
    Date date = new Date();
    if (date.getTime() - this.require_empty_out_time.getTime()
        < (long) this.instruction_require_time_out) {
      log.trace("触发时间因为小于{}毫秒，而被无视", this.instruction_require_time_out);
      return;
    } else {
      this.require_empty_out_time = date;
      if (StrUtil.equals(paramService.findByCode(AcsConfig.HASWMS).getValue(), "1")) {
        message = "申请空盘出库任务中...";
        JSONObject apply = new JSONObject();
        apply.put("device_code", device_code);
        apply.put("type", "3");
        String str = acsToWmsService.applyTaskToWms(apply);
        JSONObject jo = JSON.parseObject(str);
        if (ObjectUtil.isEmpty(jo)) {
          message = "申请空盘出库接口不通";
        } else {
          if (jo.getInteger("status") == 200) {
            message = "申请空盘出库成功";
            requireEmptyOutSuccess = true;
          } else {
            requireEmptyOutSuccess = false;
            message = "申请空盘出库失败," + jo.get("message").toString();
          }
        }
      }
    }
  }
}
