package com.zy.core.thread.impl;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.mapper.EntityWrapper;
|
import com.core.common.DateUtils;
|
import com.core.common.SpringUtils;
|
import com.zy.asrs.entity.BasLift;
|
import com.zy.asrs.entity.DeviceConfig;
|
import com.zy.asrs.entity.DeviceDataLog;
|
import com.zy.asrs.service.BasLiftService;
|
import com.zy.asrs.service.DeviceDataLogService;
|
import com.zy.asrs.utils.Utils;
|
import com.zy.common.ExecuteSupport;
|
import com.zy.common.model.LiftPointModel;
|
import com.zy.common.utils.RedisUtil;
|
import com.zy.core.News;
|
import com.zy.core.action.LiftAction;
|
import com.zy.core.cache.OutputQueue;
|
import com.zy.core.enums.*;
|
import com.zy.core.model.CommandResponse;
|
import com.zy.core.model.DeviceCommandMsgModel;
|
import com.zy.core.model.DeviceMsgModel;
|
import com.zy.core.model.LiftStation;
|
import com.zy.core.model.command.LiftCommand;
|
import com.zy.core.model.protocol.LiftProtocol;
|
import com.zy.core.model.protocol.LiftStaProtocol;
|
import com.zy.core.thread.LiftThread;
|
import com.zy.core.utils.DeviceMsgUtils;
|
import lombok.Data;
|
import lombok.extern.slf4j.Slf4j;
|
|
import java.io.IOException;
|
import java.text.MessageFormat;
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.TreeSet;
|
|
@Slf4j
|
@SuppressWarnings("all")
|
public class NyLiftThread implements LiftThread {
|
|
private DeviceConfig device;
|
private LiftProtocol liftProtocol;
|
private RedisUtil redisUtil;
|
LiftPointModel liftPointModel;
|
private List<LiftStaProtocol> liftStaProtocols = new ArrayList<>();
|
private List<DeviceMsgModel> readResultList = new ArrayList<>();
|
private List<DeviceMsgModel> resultList = new ArrayList<>();
|
|
public NyLiftThread(DeviceConfig device, LiftPointModel liftPointModel, List<LiftStation> stationList, RedisUtil redisUtil) {
|
this.device = device;
|
this.redisUtil = redisUtil;
|
this.liftPointModel = liftPointModel;
|
//初始化站点
|
for (LiftStation station : stationList) {
|
LiftStaProtocol liftStaProtocol = new LiftStaProtocol();
|
liftStaProtocol.setStaNo(station.getStaNo());//站点号
|
liftStaProtocol.setLev(station.getLev());//站点楼层
|
String locNo = Utils.getLocNo(station.getRow(), station.getBay(), station.getLev());
|
liftStaProtocol.setLocNo(locNo);//站点库位号
|
liftStaProtocol.setLiftNo(station.getLiftNo());//提升机号
|
liftStaProtocols.add(liftStaProtocol);
|
}
|
}
|
|
@Override
|
public boolean connect() {
|
return true;
|
}
|
|
@Override
|
public void close() {
|
|
}
|
|
@Override
|
public void run() {
|
News.info("{}号提升机线程启动", device.getDeviceNo());
|
|
this.connect();
|
//设备读取
|
Thread readThread = new Thread(() -> {
|
while (true) {
|
try {
|
listenMessageFromRedis();
|
readStatus();
|
Thread.sleep(100);
|
} catch (Exception e) {
|
log.error("LiftThread Fail", e);
|
}
|
}
|
});
|
readThread.start();
|
|
while (true) {
|
try {
|
execute();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
|
private void execute() {
|
LiftAction liftAction = null;
|
try {
|
liftAction = SpringUtils.getBean(LiftAction.class);
|
}catch (Exception e){}
|
if (liftAction == null) {
|
return;
|
}
|
|
Object object = redisUtil.get(RedisKeyType.LIFT_FLAG.key + device.getDeviceNo());
|
if (object == null) {
|
return;
|
}
|
|
Integer taskNo = Integer.valueOf(String.valueOf(object));
|
if (taskNo != 0) {
|
//存在任务需要执行
|
boolean result = liftAction.executeWork(device.getDeviceNo(), taskNo);
|
}
|
}
|
|
private void readStatus() {
|
try {
|
//获取提升机数据
|
DeviceMsgUtils deviceMsgUtils = null;
|
try {
|
deviceMsgUtils = SpringUtils.getBean(DeviceMsgUtils.class);
|
}catch (Exception e){
|
|
}
|
if(deviceMsgUtils == null){
|
return;
|
}
|
|
LiftCommand readStatusCommand = getReadStatusCommand();
|
//指令超过2条,不再下发任务状态请求
|
TreeSet<String> deviceCommandMsgListKey = deviceMsgUtils.getDeviceCommandMsgListKey(SlaveType.Lift, device.getDeviceNo());
|
if (deviceCommandMsgListKey.size() < 2) {
|
requestCommand(readStatusCommand);//请求状态
|
}
|
|
if (this.readResultList.isEmpty()) {
|
return;
|
}
|
|
DeviceMsgModel deviceMsgModel = this.readResultList.get(0);
|
this.readResultList.remove(0);
|
JSONObject deviceMsg = JSON.parseObject(JSON.toJSONString(deviceMsgModel.getDeviceMsg()));
|
if (!deviceMsg.getString("result").equals("success")) {
|
return;
|
}
|
JSONObject data = deviceMsg.getJSONObject("deviceStatus");
|
|
if (null == liftProtocol) {
|
liftProtocol = new LiftProtocol();
|
liftProtocol.setLiftNo(device.getDeviceNo());
|
liftProtocol.setProtocolStatus(LiftProtocolStatusType.NONE);
|
|
InnerLiftExtend innerLiftExtend = new InnerLiftExtend();
|
liftProtocol.setExtend(innerLiftExtend);
|
}
|
|
//----------读取提升机状态-----------
|
//模式
|
liftProtocol.setModel(data.getInteger("model"));
|
//PLC任务号
|
liftProtocol.setPlcTaskNo(data.getInteger("plcTaskNo"));
|
//任务状态
|
liftProtocol.setProtocolStatus(data.getInteger("protocolStatus"));
|
//任务模式
|
liftProtocol.setTaskMode(data.getInteger("taskMode"));
|
//取货数据
|
liftProtocol.setPick(data.getInteger("pick"));
|
//放货数据
|
liftProtocol.setPut(data.getInteger("put"));
|
//有托盘
|
liftProtocol.setHasTray(data.getInteger("hasTray") == 1);
|
//有小车
|
liftProtocol.setHasCar(data.getInteger("hasCar") == 1);
|
//出入库模式
|
liftProtocol.setIOMode(data.getInteger("iOMode"));
|
//故障码
|
liftProtocol.setErrorCode(data.getInteger("errorCode"));
|
//当前层
|
liftProtocol.setLev(data.getInteger("lev"));
|
|
//************补充扩展字段*************
|
InnerLiftExtend liftExtend = (InnerLiftExtend) liftProtocol.getExtend();
|
liftProtocol.setExtend(liftExtend);
|
liftExtend.setFrontOverrun(data.getBoolean("frontOverrun"));
|
liftExtend.setBackOverrun(data.getBoolean("backOverrun"));
|
liftExtend.setLeftOverrun(data.getBoolean("leftOverrun"));
|
liftExtend.setRightOverrun(data.getBoolean("rightOverrun"));
|
liftExtend.setOverHeight(data.getBoolean("overHeight"));
|
liftExtend.setOverWeight(data.getBoolean("overWeight"));
|
|
JSONArray trayList = data.getJSONArray("trayList");
|
for (int i = 0; i < trayList.size(); i++) {
|
int hasTray = (int) trayList.get(i);
|
LiftStaProtocol liftStaProtocol = liftStaProtocols.get(i);
|
liftStaProtocol.setHasTray(hasTray == 1);
|
}
|
|
JSONArray carList = data.getJSONArray("carList");
|
for (int i = 0; i < carList.size(); i++) {
|
int hasCar = (int) carList.get(i);
|
LiftStaProtocol liftStaProtocol = liftStaProtocols.get(i);
|
liftStaProtocol.setHasCar(hasCar == 1);
|
}
|
|
if (System.currentTimeMillis() - liftProtocol.getDeviceDataLog() > 1000 * 5) {
|
//采集时间超过5s,保存一次数据记录
|
//保存数据记录
|
DeviceDataLogService deviceDataLogService = SpringUtils.getBean(DeviceDataLogService.class);
|
DeviceDataLog deviceDataLog = new DeviceDataLog();
|
deviceDataLog.setOriginData(JSON.toJSONString(data));
|
deviceDataLog.setWcsData(JSON.toJSONString(liftProtocol));
|
deviceDataLog.setType("lift");
|
deviceDataLog.setDeviceNo(liftProtocol.getLiftNo());
|
deviceDataLog.setCreateTime(new Date());
|
deviceDataLogService.insert(deviceDataLog);
|
|
//更新采集时间
|
liftProtocol.setDeviceDataLog(System.currentTimeMillis());
|
}
|
|
//将提升机状态保存至数据库
|
BasLiftService basLiftService = SpringUtils.getBean(BasLiftService.class);
|
BasLift basLift = basLiftService.selectOne(new EntityWrapper<BasLift>()
|
.eq("lift_no", device.getDeviceNo()));
|
if (basLift == null) {
|
basLift = new BasLift();
|
//提升机号
|
basLift.setLiftNo(liftProtocol.getLiftNo());
|
basLift.setStatus(1);
|
basLiftService.insert(basLift);
|
}
|
//任务号
|
basLift.setWrkNo(liftProtocol.getTaskNo());
|
//修改时间
|
basLift.setUpdateTime(new Date());
|
//设备状态
|
basLift.setDeviceStatus(JSON.toJSONString(liftProtocol));
|
if (basLiftService.updateById(basLift)) {
|
OutputQueue.LIFT.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), liftProtocol.getLiftNo()));
|
}
|
|
} catch (Exception e) {
|
e.printStackTrace();
|
OutputQueue.LIFT.offer(MessageFormat.format("【{0}】读取提升机状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), device.getDeviceNo(), device.getIp(), device.getPort()));
|
}
|
}
|
|
@Override
|
public LiftProtocol getStatus(boolean clone) {
|
if (this.liftProtocol == null) {
|
return null;
|
}
|
return clone ? this.liftProtocol.clone() : this.liftProtocol;
|
}
|
|
@Override
|
public List<LiftStaProtocol> getLiftStaProtocols() {
|
return this.liftStaProtocols;
|
}
|
|
@Override
|
public LiftProtocol getStatus() {
|
return getStatus(true);
|
}
|
|
@Override
|
public CommandResponse pickAndPut(LiftCommand command) {
|
CommandResponse response = new CommandResponse(false);
|
try {
|
//发出请求
|
String resultKey = requestCommand(command);
|
//查询请求结果
|
JSONObject result = queryCommandStatus(resultKey);
|
if (result == null) {
|
return response;//请求失败
|
}
|
if(!result.getString("result").equals("success")) {
|
return response;//请求失败
|
}
|
|
this.liftProtocol.setSendTime(System.currentTimeMillis());//指令下发时间
|
response.setMessage(JSON.toJSONString(result));
|
response.setResult(true);
|
return response;
|
} catch (Exception e) {
|
e.printStackTrace();
|
response.setMessage(e.getMessage());
|
return response;
|
}
|
}
|
|
@Override
|
public CommandResponse shuttleSwitch(LiftCommand command) {
|
CommandResponse response = new CommandResponse(false);
|
try {
|
//发出请求
|
String resultKey = requestCommand(command);
|
//查询请求结果
|
JSONObject result = queryCommandStatus(resultKey);
|
if (result == null) {
|
return response;//请求失败
|
}
|
if(!result.getString("result").equals("success")) {
|
return response;//请求失败
|
}
|
|
this.liftProtocol.setSendTime(System.currentTimeMillis());//指令下发时间
|
response.setMessage(JSON.toJSONString(result));
|
response.setResult(true);
|
return response;
|
} catch (Exception e) {
|
e.printStackTrace();
|
response.setMessage(e.getMessage());
|
return response;
|
}
|
}
|
|
@Override
|
public CommandResponse move(LiftCommand command) {
|
CommandResponse response = new CommandResponse(false);
|
try {
|
//发出请求
|
String resultKey = requestCommand(command);
|
//查询请求结果
|
JSONObject result = queryCommandStatus(resultKey);
|
if (result == null) {
|
return response;//请求失败
|
}
|
if(!result.getString("result").equals("success")) {
|
return response;//请求失败
|
}
|
|
this.liftProtocol.setSendTime(System.currentTimeMillis());//指令下发时间
|
response.setMessage(JSON.toJSONString(result));
|
response.setResult(true);
|
return response;
|
} catch (Exception e) {
|
e.printStackTrace();
|
response.setMessage(e.getMessage());
|
return response;
|
}
|
}
|
|
@Override
|
public CommandResponse switchIOMode(LiftCommand command) {
|
CommandResponse response = new CommandResponse(false);
|
try {
|
//发出请求
|
String resultKey = requestCommand(command);
|
//查询请求结果
|
JSONObject result = queryCommandStatus(resultKey);
|
if (result == null) {
|
return response;//请求失败
|
}
|
if(!result.getString("result").equals("success")) {
|
return response;//请求失败
|
}
|
|
this.liftProtocol.setSendTime(System.currentTimeMillis());//指令下发时间
|
response.setMessage(JSON.toJSONString(result));
|
response.setResult(true);
|
return response;
|
} catch (Exception e) {
|
e.printStackTrace();
|
response.setMessage(e.getMessage());
|
return response;
|
}
|
}
|
|
@Override
|
public CommandResponse reset() {
|
CommandResponse response = new CommandResponse(false);
|
try {
|
LiftCommand resetCommand = getResetCommand(9999);
|
|
//发出请求
|
String resultKey = requestCommand(resetCommand);
|
//查询请求结果
|
JSONObject result = queryCommandStatus(resultKey);
|
if (result == null) {
|
return response;//请求失败
|
}
|
if(!result.getString("result").equals("success")) {
|
return response;//请求失败
|
}
|
|
this.liftProtocol.setSendTime(System.currentTimeMillis());//指令下发时间
|
response.setMessage(JSON.toJSONString(result));
|
response.setResult(true);
|
return response;
|
} catch (Exception e) {
|
e.printStackTrace();
|
response.setMessage(e.getMessage());
|
return response;
|
}
|
}
|
|
@Override
|
public boolean isIdle() {
|
if (this.liftProtocol.getTaskNo() == null
|
|| this.liftProtocol.getPlcTaskNo() == null
|
|| this.liftProtocol.getProtocolStatus() == null
|
|| this.liftProtocol.getModel() == null
|
|| this.liftProtocol.getErrorCode() == null
|
|| this.liftProtocol.getExtend() == null
|
) {
|
return false;
|
}
|
|
InnerLiftExtend extend = (InnerLiftExtend) this.liftProtocol.getExtend();
|
|
boolean res = this.liftProtocol.getProtocolStatus() == LiftProtocolStatusType.IDLE.id
|
&& this.liftProtocol.getPlcTaskNo() == 0
|
&& this.liftProtocol.getTaskNo() == 0
|
&& this.liftProtocol.getModel() == 2
|
&& this.liftProtocol.getErrorCode() == 0
|
&& !extend.getFrontOverrun()
|
&& !extend.getBackOverrun()
|
&& !extend.getLeftOverrun()
|
&& !extend.getRightOverrun()
|
&& !extend.getOverHeight()
|
&& !extend.getOverWeight()
|
;
|
return res;
|
}
|
|
@Override
|
public boolean isDeviceIdle() {
|
return isDeviceIdle(null);
|
}
|
|
@Override
|
public boolean isDeviceIdle(ExecuteSupport support) {
|
if (null != support) {
|
Boolean judgement = support.judgement();
|
if (judgement != null && !judgement) {
|
return true;
|
}
|
}
|
|
if (this.liftProtocol.getProtocolStatus() == null
|
|| this.liftProtocol.getModel() == null
|
|| this.liftProtocol.getErrorCode() == null
|
|| this.liftProtocol.getExtend() == null
|
) {
|
return false;
|
}
|
|
InnerLiftExtend extend = (InnerLiftExtend) this.liftProtocol.getExtend();
|
|
boolean res = this.liftProtocol.getProtocolStatus() == LiftProtocolStatusType.IDLE.id
|
&& this.liftProtocol.getModel() == 2
|
&& this.liftProtocol.getErrorCode() == 0
|
&& !extend.getFrontOverrun()
|
&& !extend.getBackOverrun()
|
&& !extend.getLeftOverrun()
|
&& !extend.getRightOverrun()
|
&& !extend.getOverHeight()
|
&& !extend.getOverWeight()
|
;
|
return res;
|
}
|
|
@Override
|
public boolean setProtocolStatus(LiftProtocolStatusType status) {
|
this.liftProtocol.setProtocolStatus(status);
|
return true;
|
}
|
|
@Override
|
public boolean setSyncTaskNo(Integer taskNo) {
|
this.liftProtocol.setSyncTaskNo(taskNo);
|
return true;
|
}
|
|
@Override
|
public int generateDeviceTaskNo(int taskNo, LiftTaskModeType type) {
|
return taskNo;
|
}
|
|
@Override
|
public String getCurrentLocNo() {
|
if (liftProtocol.getLev() == null) {
|
return null;
|
}
|
return Utils.getLocNo(liftPointModel.getRow(), liftPointModel.getBay(), liftProtocol.getLev());
|
}
|
|
@Override
|
public LiftCommand getPickAndPutCommand(Integer taskNo, Integer pick, Integer put) {
|
LiftCommand command = new LiftCommand();
|
command.setLiftNo(device.getDeviceNo());
|
command.setTaskNo(taskNo);
|
command.setMode(LiftTaskModeType.PICK_PUT.id);
|
command.setPick(pick);
|
command.setPut(put);
|
|
return command;
|
}
|
|
@Override
|
public LiftCommand getShuttleSwitchCommand(Integer taskNo, Integer pick, Integer put) {
|
LiftCommand command = new LiftCommand();
|
command.setLiftNo(device.getDeviceNo());
|
command.setTaskNo(taskNo);
|
command.setMode(LiftTaskModeType.SHUTTLE_SWITCH.id);
|
command.setPick(pick);
|
command.setPut(put);
|
|
return command;
|
}
|
|
@Override
|
public LiftCommand getMoveCommand(Integer taskNo, Integer pick, Integer put) {
|
LiftCommand command = new LiftCommand();
|
command.setLiftNo(device.getDeviceNo());
|
command.setTaskNo(taskNo);
|
command.setMode(LiftTaskModeType.MOVE.id);
|
command.setPick(pick);
|
command.setPut(put);
|
|
return command;
|
}
|
|
@Override
|
public LiftCommand getSwitchIOCommand(Integer taskNo, LiftIoModeType mode) {
|
LiftCommand command = new LiftCommand();
|
command.setLiftNo(device.getDeviceNo());
|
if (mode.equals(LiftIoModeType.IN)) {
|
command.setMode(LiftIoModeType.IN.id);
|
} else {
|
command.setMode(LiftIoModeType.OUT.id);
|
}
|
return command;
|
}
|
|
@Override
|
public LiftCommand getResetCommand(Integer taskNo) {
|
LiftCommand command = new LiftCommand();
|
command.setLiftNo(device.getDeviceNo());
|
command.setMode(LiftTaskModeType.RESET.id);
|
return command;
|
}
|
|
//获取读状态信息命令
|
private LiftCommand getReadStatusCommand() {
|
LiftCommand command = new LiftCommand();
|
command.setLiftNo(device.getDeviceNo());
|
command.setMode(LiftTaskModeType.READ_STATUS.id);
|
return command;
|
}
|
|
//发出请求
|
private String requestCommand(LiftCommand command) throws IOException {
|
try {
|
DeviceMsgUtils deviceMsgUtils = SpringUtils.getBean(DeviceMsgUtils.class);
|
if (deviceMsgUtils == null) {
|
return null;
|
}
|
|
//压缩数据包
|
JSONObject data = JSON.parseObject(JSON.toJSONString(command));
|
|
DeviceCommandMsgModel commandMsgModel = new DeviceCommandMsgModel();
|
commandMsgModel.setDeviceId(device.getDeviceNo());
|
commandMsgModel.setDeviceType(String.valueOf(SlaveType.Lift));
|
commandMsgModel.setCommand(data);
|
String key = deviceMsgUtils.sendDeviceCommand(SlaveType.Lift, device.getDeviceNo(), commandMsgModel);
|
return key;
|
}catch (Exception e) {
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
private JSONObject queryCommandStatus(String resultKey) {
|
// 获取服务器响应
|
// 尝试50次
|
JSONObject result = null;
|
for (int i = 0; i < 50; i++) {
|
result = getRequestBody(resultKey);
|
if (result == null) {
|
try {
|
Thread.sleep(500);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}else {
|
break;
|
}
|
}
|
return result;
|
}
|
|
public JSONObject getRequestBody(String resultKey) {
|
try {
|
// 获取服务器响应
|
JSONObject result = null;
|
int idx = -1;
|
for (int i = 0; i < resultList.size(); i++) {
|
DeviceMsgModel deviceMsgModel = resultList.get(i);
|
if(deviceMsgModel.getResultKey().equals(resultKey)){
|
idx = i;
|
result = JSON.parseObject(JSON.toJSONString(deviceMsgModel.getDeviceMsg()));
|
break;
|
}
|
}
|
|
if (result == null) {
|
return null;//无响应结果
|
}
|
|
resultList.remove(idx);
|
return result;
|
} catch (Exception e) {
|
return null;
|
}
|
}
|
|
private void listenMessageFromRedis() {
|
try {
|
DeviceMsgUtils deviceMsgUtils = null;
|
try {
|
deviceMsgUtils = SpringUtils.getBean(DeviceMsgUtils.class);
|
}catch (Exception e){
|
|
}
|
if (deviceMsgUtils == null) {
|
return;
|
}
|
DeviceMsgModel deviceMsg = deviceMsgUtils.getDeviceMsg(SlaveType.Lift, device.getDeviceNo());
|
if(deviceMsg == null){
|
return;
|
}
|
|
if (deviceMsg.getDeviceMsgType().equals("status")) {
|
readResultList.add(deviceMsg);
|
}else {
|
resultList.add(deviceMsg);
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
|
/**
|
* 扩展字段
|
*/
|
@Data
|
private class InnerLiftExtend {
|
|
/**
|
* 前超限
|
*/
|
private Boolean frontOverrun;
|
|
/**
|
* 后超限
|
*/
|
private Boolean backOverrun;
|
|
/**
|
* 左超限
|
*/
|
private Boolean leftOverrun;
|
|
/**
|
* 右超限
|
*/
|
private Boolean rightOverrun;
|
|
/**
|
* 超高
|
*/
|
private Boolean overHeight;
|
|
/**
|
* 超重
|
*/
|
private Boolean overWeight;
|
|
}
|
}
|