package com.zy.core.thread;
|
|
import HslCommunication.Core.Transfer.DataFormat;
|
import HslCommunication.Core.Types.OperateResult;
|
import HslCommunication.Core.Types.OperateResultExOne;
|
import HslCommunication.ModBus.ModbusTcpNet;
|
import HslCommunication.Profinet.Siemens.SiemensPLCS;
|
import HslCommunication.Profinet.Siemens.SiemensS7Net;
|
import com.alibaba.fastjson.JSON;
|
import com.core.common.DateUtils;
|
import com.core.common.SpringUtils;
|
import com.core.exception.CoolException;
|
import com.zy.asrs.entity.BasLift;
|
import com.zy.asrs.entity.BasLiftOpt;
|
import com.zy.asrs.entity.WrkMast;
|
import com.zy.asrs.mapper.WrkMastMapper;
|
import com.zy.asrs.service.BasLiftOptService;
|
import com.zy.asrs.service.BasLiftService;
|
import com.zy.asrs.utils.Utils;
|
import com.zy.common.utils.CommonUtils;
|
import com.zy.common.utils.RedisUtil;
|
import com.zy.core.DevpThread;
|
import com.zy.core.News;
|
import com.zy.core.ThreadHandler;
|
import com.zy.core.cache.MessageQueue;
|
import com.zy.core.cache.OutputQueue;
|
import com.zy.core.cache.SlaveConnection;
|
import com.zy.core.enums.*;
|
import com.zy.core.model.LiftSlave;
|
import com.zy.core.model.Task;
|
import com.zy.core.model.command.*;
|
import com.zy.core.model.protocol.LiftProtocol;
|
import com.zy.core.model.protocol.StaProtocol;
|
import lombok.Data;
|
import lombok.extern.slf4j.Slf4j;
|
|
import java.text.MessageFormat;
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.List;
|
|
/**
|
* 提升机线程
|
*/
|
@Data
|
@Slf4j
|
public class LiftThread implements Runnable, ThreadHandler {
|
|
private SiemensS7Net siemensS7Net;
|
private LiftSlave slave;
|
private LiftProtocol liftProtocol;
|
private RedisUtil redisUtil;
|
|
public LiftThread(LiftSlave slave,RedisUtil redisUtil) {
|
this.slave = slave;
|
this.redisUtil = redisUtil;
|
}
|
|
@Override
|
public void run() {
|
this.connect();
|
while (true) {
|
try {
|
int step = 1;
|
Task task = MessageQueue.poll(SlaveType.Lift, slave.getId());
|
if (task != null) {
|
step = task.getStep();
|
}
|
switch (step) {
|
// 读数据
|
case 1:
|
read();
|
break;
|
// 写入数据
|
case 2:
|
write((NyLiftCommand) task.getData());
|
break;
|
//分配任务
|
case 3:
|
assignWork((LiftAssignCommand) task.getData());
|
break;
|
default:
|
break;
|
}
|
Thread.sleep(500);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
|
@Override
|
public boolean connect() {
|
boolean result = false;
|
//-------------------------提升机连接方法------------------------//
|
siemensS7Net = new SiemensS7Net(SiemensPLCS.S1200, slave.getIp());
|
OperateResult connect = siemensS7Net.ConnectServer();
|
if(connect.IsSuccess){
|
result = true;
|
OutputQueue.CRN.offer(MessageFormat.format( "【{0}】提升机plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
|
log.info("提升机plc连接成功 ===>> [id:{}] [ip:{}] [port:{}] ", slave.getId(), slave.getIp(), slave.getPort());
|
} else {
|
OutputQueue.CRN.offer(MessageFormat.format("【{0}】提升机plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
|
log.error("提升机plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}] ", slave.getId(), slave.getIp(), slave.getPort());
|
}
|
siemensS7Net.ConnectClose();
|
//-------------------------提升机连接方法------------------------//
|
return result;
|
}
|
|
@Override
|
public void close() {
|
siemensS7Net.ConnectClose();
|
}
|
|
private void read() {
|
try {
|
readStatus();
|
|
//提升机处于运行状态,将标记置为true
|
if (liftProtocol.getBusy()) {
|
liftProtocol.setPakMk(true);
|
}
|
|
//提升机处于未运行、就绪、标记true、有任务号
|
if (!liftProtocol.getBusy()
|
&& liftProtocol.getPakMk()
|
&& liftProtocol.getTaskNo() != 0) {
|
//还有未完成的命令
|
executeWork(liftProtocol.getTaskNo());
|
}
|
} catch (Exception e) {
|
OutputQueue.LIFT.offer(MessageFormat.format("【{0}】提升机plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
|
}
|
}
|
|
private void readStatus() {
|
try {
|
OperateResultExOne<byte[]> result = siemensS7Net.Read("M100.0", (short) 28);
|
if (result.IsSuccess) {
|
if (null == liftProtocol) {
|
liftProtocol = new LiftProtocol();
|
liftProtocol.setLiftNo(slave.getId().shortValue());
|
}
|
|
//----------读取提升机状态-----------
|
//获取数据
|
byte[] content = result.Content;
|
//模式
|
liftProtocol.setModel(siemensS7Net.getByteTransform().TransBool(content, 0));
|
//忙闲
|
liftProtocol.setBusy(siemensS7Net.getByteTransform().TransBool(content, 1));
|
//前超限
|
liftProtocol.setFrontOverrun(siemensS7Net.getByteTransform().TransBool(content, 7));
|
//后超限
|
liftProtocol.setBackOverrun(siemensS7Net.getByteTransform().TransBool(content, 8));
|
//左超限
|
liftProtocol.setLeftOverrun(siemensS7Net.getByteTransform().TransBool(content, 9));
|
//右超限
|
liftProtocol.setRightOverrun(siemensS7Net.getByteTransform().TransBool(content, 10));
|
//超高
|
liftProtocol.setOverHeight(siemensS7Net.getByteTransform().TransBool(content, 11));
|
//超重
|
liftProtocol.setOverWeight(siemensS7Net.getByteTransform().TransBool(content, 12));
|
//有托盘
|
liftProtocol.setHasTray(siemensS7Net.getByteTransform().TransBool(content, 16));
|
//有小车
|
liftProtocol.setHasCar(siemensS7Net.getByteTransform().TransBool(content, 17));
|
//设备故障
|
liftProtocol.setDeviceError(siemensS7Net.getByteTransform().TransBool(content, 18));
|
//任务号
|
liftProtocol.setTaskNo(siemensS7Net.getByteTransform().TransInt16(content, 19));
|
//任务地址
|
liftProtocol.setTaskAddress(siemensS7Net.getByteTransform().TransInt16(content, 21));
|
//目的地址
|
liftProtocol.setDistAddress(siemensS7Net.getByteTransform().TransInt16(content, 21));
|
//已完成任务号
|
liftProtocol.setCompleteTaskNo(siemensS7Net.getByteTransform().TransInt16(content, 23));
|
//当前楼层
|
liftProtocol.setLev(siemensS7Net.getByteTransform().TransInt16(content, 25));
|
|
///读取提升机状态-end
|
|
//将提升机状态保存至数据库
|
BasLiftService liftService = SpringUtils.getBean(BasLiftService.class);
|
BasLift basLift = liftService.selectById(liftProtocol.getLiftNo());
|
if (basLift == null) {
|
basLift = new BasLift();
|
//提升机号
|
basLift.setLiftNo(slave.getId());
|
liftService.insert(basLift);
|
}
|
basLift.setStatus(liftProtocol.getProtocolStatus());
|
basLift.setWrkNo(liftProtocol.getTaskNo().intValue());
|
basLift.setUpdateTime(new Date());
|
basLift.setPakMk(liftProtocol.getPakMk());
|
basLift.setModel(liftProtocol.getModel());
|
basLift.setBusy(liftProtocol.getBusy());
|
basLift.setFrontOverrun(liftProtocol.getFrontOverrun());
|
basLift.setBackOverrun(liftProtocol.getBackOverrun());
|
basLift.setLeftOverrun(liftProtocol.getLeftOverrun());
|
basLift.setRightOverrun(liftProtocol.getRightOverrun());
|
basLift.setOverHeight(liftProtocol.getOverHeight());
|
basLift.setOverWeight(liftProtocol.getOverWeight());
|
basLift.setHasTray(liftProtocol.getHasTray());
|
basLift.setHasCar(liftProtocol.getHasCar());
|
basLift.setDeviceError(liftProtocol.getDeviceError());
|
basLift.setTaskAddress(liftProtocol.getTaskAddress().intValue());
|
basLift.setDistAddress(liftProtocol.getDistAddress().intValue());
|
basLift.setCompleteTaskNo(liftProtocol.getCompleteTaskNo().intValue());
|
basLift.setLev(liftProtocol.getLev().intValue());
|
if (liftService.updateById(basLift)) {
|
OutputQueue.LIFT.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
|
// log.info(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
|
}
|
|
}else {
|
OutputQueue.LIFT.offer(MessageFormat.format("【{0}】{1}提升机plc状态信息失败", DateUtils.convert(new Date()), slave.getId()));
|
throw new CoolException(MessageFormat.format( "提升机plc状态信息失败 ===>> [id:{0}] [ip:{1}] [port:{2}]", slave.getId(), slave.getIp(), slave.getPort()));
|
}
|
} catch (Exception e) {
|
OutputQueue.LIFT.offer(MessageFormat.format("【{0}】提升机plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
|
}
|
}
|
|
private boolean write(NyLiftCommand command){
|
if (null == command) {
|
News.error("提升机写入命令为空");
|
return false;
|
}
|
|
command.setLiftNo(slave.getId().shortValue());
|
short[] array = getCommandArr(command);//获取命令报文
|
|
OperateResult result = siemensS7Net.Write("41088", array);
|
if (result != null && result.IsSuccess) {
|
News.info("提升机命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command));
|
OutputQueue.LIFT.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
|
return true;
|
} else {
|
OutputQueue.LIFT.offer(MessageFormat.format("【{0}】写入提升机plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}],次数:{}", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
|
News.error("写入提升机plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
|
return false;
|
}
|
}
|
|
//获取命令报文
|
private short[] getCommandArr(NyLiftCommand command) {
|
// 开始任务
|
short[] array = new short[4];
|
if (command.getTaskModel() != null) {
|
//任务类型
|
array[0] = command.getTaskModel();
|
}
|
if (command.getSourceSta() != null) {
|
//源站台编号
|
array[1] = command.getSourceSta();
|
}
|
if (command.getTargetSta() != null) {
|
//目标站台编号
|
array[2] = command.getTargetSta();
|
}
|
if (command.getTaskNo() != null) {
|
//任务号
|
array[3] = command.getTaskNo();
|
}
|
return array;
|
}
|
|
//分配任务
|
private void assignWork(LiftAssignCommand assignCommand) {
|
LiftRedisCommand redisCommand = new LiftRedisCommand();
|
redisCommand.setLiftNo(assignCommand.getLiftNo());//提升机号
|
redisCommand.setWrkNo(assignCommand.getTaskNo());//工作号
|
redisCommand.setCommandStep(0);//命令执行步序
|
redisCommand.setAssignCommand(assignCommand);//命令
|
//任务数据保存到redis
|
redisUtil.set("lift_wrk_no_" + assignCommand.getTaskNo(), JSON.toJSONString(redisCommand));
|
liftProtocol.setAssignCommand(assignCommand);
|
liftProtocol.setProtocolStatus(LiftProtocolStatusType.WORKING);
|
//执行下发任务
|
executeWork(assignCommand.getTaskNo());
|
}
|
|
//执行任务
|
private boolean executeWork(Short wrkNo) {
|
//读取redis数据
|
if (wrkNo == null) {
|
return false;
|
}
|
|
WrkMastMapper wrkMastMapper = SpringUtils.getBean(WrkMastMapper.class);
|
Object o = redisUtil.get("lift_wrk_no_" + wrkNo);
|
if (o == null) {
|
return false;
|
}
|
LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
|
List<NyLiftCommand> commands = redisCommand.getAssignCommand().getCommands();
|
//当前步序
|
int commandStep = redisCommand.getCommandStep();
|
//总步序
|
int size = commands.size();
|
|
//取出命令
|
NyLiftCommand command = commands.get(commandStep);
|
|
//下发命令
|
if (!write(command)) {
|
News.error("提升机命令下发失败,提升机号={},任务数据={}", command.getLiftNo(), JSON.toJSON(command));
|
return false;
|
}
|
|
News.info("提升机命令下发成功,提升机号={},任务数据={}", command.getLiftNo(), JSON.toJSON(command));
|
|
//将标记置为false(防止重发)
|
liftProtocol.setPakMk(false);
|
|
//保存数据到数据库做流水
|
BasLiftOptService liftOptService = SpringUtils.getBean(BasLiftOptService.class);
|
if (liftOptService != null) {
|
short[] commandArr = getCommandArr(command);//获取命令报文
|
BasLiftOpt opt = new BasLiftOpt(
|
redisCommand.getWrkNo().intValue(),
|
redisCommand.getLiftNo().intValue(),
|
new Date(),
|
null,
|
null,
|
null,
|
JSON.toJSONString(command),
|
JSON.toJSONString(commandArr)
|
);
|
liftOptService.insert(opt);
|
}
|
|
//判断数据是否执行完成
|
if (commandStep < size - 1) {
|
//更新redis数据
|
//步序增加
|
commandStep++;
|
redisCommand.setCommandStep(commandStep);
|
//任务数据保存到redis
|
redisUtil.set("lift_wrk_no_" + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand));
|
}else {
|
//已执行完成
|
//删除redis
|
redisUtil.del("lift_wrk_no_" + redisCommand.getWrkNo());
|
|
//对主线程抛出等待确认状态waiting
|
liftProtocol.setProtocolStatus(LiftProtocolStatusType.WAITING);
|
News.info("提升机任务执行下发完成等待执行结束,提升机号={},任务数据={}", command.getLiftNo(), JSON.toJSON(command));
|
}
|
|
return true;
|
}
|
|
/******************************************************************************************/
|
/**************************************** 测试专用 *****************************************/
|
/*****************************************************************************************/
|
public static void main(String[] args) throws InterruptedException {
|
LiftSlave slave = new LiftSlave();
|
slave.setId(1);
|
slave.setIp("192.168.4.24");
|
slave.setPort(502);
|
// LiftThread thread = new LiftThread(slave,);
|
// thread.connect();
|
// thread.readStatus();
|
//
|
// LiftCommand command = new LiftCommand();
|
// command.setRun((short) 1);
|
// command.setDistPosition((short) 12);
|
// command.setSpeed((short) 300);
|
// command.setHeight2((short) 100);
|
// command.setHeight3((short) 200);
|
// command.setHeight4((short) 303);
|
// command.setLiftLock(true);
|
// thread.write(command);
|
|
}
|
|
}
|