package com.zy.acs.conveyor.core.thread;
|
|
import com.alibaba.fastjson.JSON;
|
import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
|
import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
|
import com.zy.acs.common.utils.ByteUtils;
|
import com.zy.acs.common.utils.News;
|
import com.zy.acs.conveyor.core.DevpThread;
|
import com.zy.acs.conveyor.core.cache.MessageQueue;
|
import com.zy.acs.conveyor.core.cache.OutputQueue;
|
import com.zy.acs.conveyor.core.cache.SlaveConnection;
|
import com.zy.acs.conveyor.core.constant.DeviceField;
|
import com.zy.acs.conveyor.core.constant.PlcConstant;
|
import com.zy.acs.conveyor.core.constant.StationStatusField;
|
import com.zy.acs.conveyor.core.constant.TaskField;
|
import com.zy.acs.conveyor.core.enums.SlaveType;
|
import com.zy.acs.conveyor.core.enums.TaskType;
|
import com.zy.acs.conveyor.core.model.Task;
|
import com.zy.acs.conveyor.core.model.protocol.StaProtocol;
|
import com.zy.acs.conveyor.core.properties.DevpSlave;
|
import com.zy.acs.conveyor.entity.Devp;
|
import com.zy.acs.conveyor.service.DevpService;
|
import com.zy.acs.conveyor.utils.SpringContextUtil;
|
import com.zy.acs.framework.common.Cools;
|
import com.zy.acs.framework.common.DateUtils;
|
import lombok.Data;
|
import lombok.extern.slf4j.Slf4j;
|
|
import java.text.MessageFormat;
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.concurrent.ConcurrentHashMap;
|
|
/**
|
* 输送线线程
|
* Created by vincent on 2020/8/4
|
*/
|
@Data
|
@Slf4j
|
public class S7DevpThread implements Runnable, DevpThread {
|
|
private DevpSlave slave;
|
|
private S7PLC s7PLC;
|
|
private Map<Integer, StaProtocol> station = new ConcurrentHashMap<>();
|
|
|
@Override
|
@SuppressWarnings("InfiniteLoopStatement")
|
public void run() {
|
connect();
|
while (true) {
|
try {
|
TaskType step = TaskType.READ;
|
Task task = MessageQueue.poll(SlaveType.Devp, slave.getId());
|
if (task != null) {
|
step = task.getStep();
|
}
|
switch (step) {
|
// 读数据
|
case READ:
|
read();
|
break;
|
// 写数据 ID+目标站
|
case WRITE:
|
write((StaProtocol) task.getData());
|
break;
|
default:
|
break;
|
}
|
Thread.sleep(100);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
|
}
|
}
|
|
|
@Override
|
public boolean connect() {
|
s7PLC = new S7PLC(EPlcType.S1200, slave.getIp());
|
s7PLC.connect();
|
return true;
|
}
|
|
/**
|
* 读取状态 ====> 整块plc
|
*/
|
private void read() throws InterruptedException {
|
List<Integer> staNos = slave.getStaNos();
|
int staNoSize = staNos.size();
|
byte[] stationStatus = s7PLC.readByte(StationStatusField.TASK_NUMBER.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION + StationStatusField.TASK_NUMBER.getOffset(), StationStatusField.TASK_NUMBER.getOffset() + staNoSize * PlcConstant.STATION_STATUS_LENGTH);
|
for (int i = 0; i < staNoSize; i++) {
|
// 站点编号
|
Integer siteId = staNos.get(i);
|
StaProtocol staProtocol = station.get(siteId);
|
if (null == staProtocol) {
|
staProtocol = new StaProtocol();
|
staProtocol.setSiteId(siteId);
|
station.put(siteId, staProtocol);
|
}
|
staProtocol.setWorkNo((int) ByteUtils.getLong(stationStatus, StationStatusField.TASK_NUMBER.getOffset() + i * PlcConstant.STATION_STATUS_LENGTH));
|
staProtocol.setStaNo((int) ByteUtils.getShort(stationStatus, StationStatusField.FINAL_TARGET.getOffset() + i * PlcConstant.STATION_STATUS_LENGTH));
|
boolean[] status = ByteUtils.getBooleans(stationStatus, StationStatusField.STATUS_WORD.getOffset() + i * PlcConstant.STATION_STATUS_LENGTH, StationStatusField.STATUS_WORD.getByteLength());
|
staProtocol.setAutoing(status[0]); // 自动
|
staProtocol.setLoading(status[1]); // 有物
|
staProtocol.setInEnable(status[2]); // 可入
|
staProtocol.setOutEnable(status[3]);// 可出
|
staProtocol.setEmptyMk(status[4]); // 空板信号
|
staProtocol.setFullPlt(status[5]); // 满托盘
|
staProtocol.setHigh(status[6]); // 高库位
|
staProtocol.setLow(status[7]); // 低库位
|
if (!staProtocol.isPakMk() && !staProtocol.isLoading()) {
|
staProtocol.setPakMk(true);
|
}
|
}
|
|
byte[] deviceField = s7PLC.readByte(DeviceField.BARCODE.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION + DeviceField.BARCODE.getOffset(), DeviceField.BARCODE.getOffset() + DeviceField.BARCODE.getByteLength() * slave.getBarcodeSize());
|
for (int i = 0; i < slave.getBarcodeSize(); i++) {
|
String barcode = ByteUtils.getString(deviceField, i * DeviceField.BARCODE.getByteLength(), DeviceField.BARCODE.getByteLength());
|
BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, i);
|
if (Cools.isEmpty(barcode)) {
|
barcodeThread.clearBarcode();
|
} else {
|
if (!Cools.isEmpty(barcodeThread) && !barcodeThread.getBarcode().equals(barcode)) {
|
barcodeThread.setBarcode(barcode);
|
log.info("料箱码:{}", barcode);
|
}
|
}
|
}
|
|
OutputQueue.DEVP.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功", DateUtils.convert(new Date()), slave.getId()));
|
|
// 根据实时信息更新数据库
|
try {
|
List<Devp> devps = new ArrayList<>();
|
for (Integer siteId : staNos) {
|
StaProtocol staProtocol = station.get(siteId);
|
devps.add(staProtocol.toSqlModel());
|
}
|
DevpService devpService = SpringContextUtil.getBean(DevpService.class);
|
if (null != devpService) {
|
devpService.updateBatchByDevpNo(devps);
|
} else {
|
throw new Exception("更新数据库数据失败");
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
OutputQueue.DEVP.offer(MessageFormat.format("【{0}】更新数据库数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
|
News.error("SiemensDevp" + " - 3" + " - 更新数据库数据失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
|
}
|
|
|
}
|
|
/**
|
* 写入 ID+目标站 =====> 单站点写入
|
*/
|
private void write(StaProtocol staProtocol) throws InterruptedException {
|
if (null == staProtocol) {
|
return;
|
}
|
List<Integer> staNos = slave.getStaNos();
|
int index = staNos.indexOf(staProtocol.getSiteId());
|
|
s7PLC.writeInt32(TaskField.TASK_NUMBER.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION + (TaskField.DEST_STATION.getOffset() + index * PlcConstant.TASK_LENGTH), staProtocol.getWorkNo()); // 工作号
|
Thread.sleep(100);
|
s7PLC.writeInt16(TaskField.DEST_STATION.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION + (index * PlcConstant.TASK_LENGTH + TaskField.DEST_STATION.getOffset() + TaskField.DEST_STATION.getAddressPattern()), staProtocol.getStaNo().shortValue()); // 目标站
|
|
OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(staProtocol)));
|
News.error("SiemensDevp" + " - 4" + " - 写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(staProtocol));
|
}
|
|
|
@Override
|
public void close() {
|
s7PLC.close();
|
}
|
|
|
}
|