| New file |
| | |
| | | package com.zy.acs.conveyor.core.thread; |
| | | |
| | | import HslCommunication.Core.Types.OperateResultExOne; |
| | | import HslCommunication.Profinet.Siemens.SiemensS7Net; |
| | | import com.zy.acs.common.utils.News; |
| | | import com.zy.acs.conveyor.core.constant.DeviceField; |
| | | import com.zy.acs.conveyor.core.constant.PlcAlarmDefinition; |
| | | import com.zy.acs.conveyor.core.constant.StationStatusField; |
| | | import com.zy.acs.conveyor.core.model.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 lombok.Data; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 输送线线程 |
| | | * Created by vincent on 2020/8/4 |
| | | */ |
| | | @Data |
| | | @Slf4j |
| | | public class SiemensDevpThread implements Runnable { |
| | | |
| | | private DevpSlave slave; |
| | | |
| | | private SiemensS7Net siemensS7Net; |
| | | |
| | | private Map<Integer, StaProtocol> station; |
| | | |
| | | private volatile boolean connected = false; |
| | | |
| | | private static final int WRITE_RETRY_MAX = 5; |
| | | |
| | | private static final int WRITE_RETRY_INTERVAL_MS = 200; |
| | | |
| | | private static final int READ_INTERVAL_MS = 100; |
| | | |
| | | private static final int DB_UPDATE_INTERVAL_MS = 2000; // 数据库更新间隔 |
| | | |
| | | private long lastDbUpdateTime = 0; |
| | | |
| | | |
| | | public SiemensDevpThread(DevpSlave slave, SiemensS7Net siemensS7Net, Map<Integer, StaProtocol> station) { |
| | | this.slave = slave; |
| | | this.siemensS7Net = siemensS7Net; |
| | | this.station = station; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | @SuppressWarnings("InfiniteLoopStatement") |
| | | public void run() { |
| | | while (!Thread.currentThread().isInterrupted()) { |
| | | try { |
| | | read(); |
| | | Thread.sleep(READ_INTERVAL_MS); |
| | | } catch (InterruptedException e) { |
| | | Thread.currentThread().interrupt(); |
| | | log.warn("SiemensDevp线程被中断 [id:{}]", slave.getId()); |
| | | break; |
| | | } catch (Exception e) { |
| | | log.error("SiemensDevp线程运行异常 [id:{}]", slave.getId(), e); |
| | | } |
| | | } |
| | | log.info("SiemensDevp读线程已退出 [id:{}]", slave.getId()); |
| | | } |
| | | |
| | | /** |
| | | * 读取状态 ====> 整块plc |
| | | */ |
| | | private void read() throws InterruptedException { |
| | | if (!connected || siemensS7Net == null) { |
| | | log.warn("PLC未连接,跳过读取 [id:{}]", slave.getId()); |
| | | return; |
| | | } |
| | | |
| | | List<Integer> staNos = slave.getStaNos(); |
| | | int staNoSize = staNos.size(); |
| | | |
| | | // 读取站点状态 |
| | | OperateResultExOne<byte[]> result = siemensS7Net.Read( |
| | | StationStatusField.ALL.buildAddress(), |
| | | (short) (staNoSize * StationStatusField.ALL.getByteLength())); |
| | | |
| | | if (!result.IsSuccess) { |
| | | log.error("读取站点状态失败 [id:{}] [error:{}]", slave.getId(), result.Message); |
| | | connected = false; |
| | | return; |
| | | } |
| | | |
| | | byte[] content = result.Content; |
| | | for (int i = 0; i < staNoSize; i++) { |
| | | StaProtocol staProtocol = station.get(staNos.get(staNoSize)); |
| | | parseStationStatus(content, i, staProtocol); |
| | | } |
| | | |
| | | // 读取条码 |
| | | readBarcodes(); |
| | | |
| | | // 读取外形检测错误 |
| | | readDimensionErrors(); |
| | | |
| | | // 读取PLC故障 |
| | | readPlcAlarms(staNos, staNoSize); |
| | | |
| | | // 定期更新数据库(降低频率) |
| | | updateDatabaseIfNeeded(); |
| | | } |
| | | |
| | | /** |
| | | * 解析单个站点状态 |
| | | */ |
| | | private void parseStationStatus(byte[] content, int index, StaProtocol staProtocol) { |
| | | int offset = index * StationStatusField.ALL.getByteLength(); |
| | | staProtocol.setWorkNo(siemensS7Net.getByteTransform().TransInt32(content, offset)); |
| | | staProtocol.setStaNo((int) siemensS7Net.getByteTransform().TransInt16( |
| | | content, offset + StationStatusField.FINAL_TARGET.getOffset())); |
| | | |
| | | boolean[] status = siemensS7Net.getByteTransform().TransBool( |
| | | content, offset + StationStatusField.STATUS_WORD.getOffset(), |
| | | 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]); |
| | | |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 读取条码信息 |
| | | */ |
| | | private void readBarcodes() { |
| | | List<Integer> barcodeArr = slave.getBarcodeArr(); |
| | | if (barcodeArr == null || barcodeArr.isEmpty()) { |
| | | return; |
| | | } |
| | | |
| | | OperateResultExOne<byte[]> result = siemensS7Net.Read( |
| | | DeviceField.BARCODE.buildAddress(), |
| | | (short) (barcodeArr.size() * DeviceField.BARCODE.getByteLength())); |
| | | |
| | | if (!result.IsSuccess) { |
| | | log.warn("读取条码失败 [id:{}]", slave.getId()); |
| | | return; |
| | | } |
| | | |
| | | byte[] content = result.Content; |
| | | for (int i = 0; i < barcodeArr.size(); i++) { |
| | | String barcode = siemensS7Net.getByteTransform().TransString( |
| | | content, i * DeviceField.BARCODE.getByteLength(), |
| | | DeviceField.BARCODE.getByteLength(), "UTF-8"); |
| | | |
| | | if (!Cools.isEmpty(barcode)) { |
| | | StaProtocol staProtocol = station.get(barcodeArr.get(i)); |
| | | staProtocol.setBarcode(barcode); |
| | | log.info("料箱码:{}", barcode); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 读取外形检测错误 |
| | | */ |
| | | private void readDimensionErrors() { |
| | | List<Integer> staNosError = slave.getStaNosError(); |
| | | if (staNosError == null || staNosError.isEmpty()) { |
| | | return; |
| | | } |
| | | |
| | | OperateResultExOne<byte[]> result = siemensS7Net.Read( |
| | | DeviceField.DIMENSION_WORD.buildAddress(), |
| | | (short) (staNosError.size() * DeviceField.DIMENSION_WORD.getByteLength())); |
| | | |
| | | if (!result.IsSuccess) { |
| | | log.warn("读取外形检测错误失败 [id:{}]", slave.getId()); |
| | | return; |
| | | } |
| | | |
| | | byte[] content = result.Content; |
| | | for (int i = 0; i < staNosError.size(); i++) { |
| | | Integer siteId = staNosError.get(i); |
| | | StaProtocol staProtocol = station.get(siteId); |
| | | |
| | | boolean[] status = siemensS7Net.getByteTransform().TransBool( |
| | | content, i * DeviceField.DIMENSION_WORD.getByteLength(), |
| | | DeviceField.DIMENSION_WORD.getByteLength()); |
| | | |
| | | staProtocol.setFrontErr(status[0]); |
| | | staProtocol.setBackErr(status[1]); |
| | | staProtocol.setHighErr(status[2]); |
| | | staProtocol.setLeftErr(status[3]); |
| | | staProtocol.setRightErr(status[4]); |
| | | staProtocol.setWeightErr(status[5]); |
| | | staProtocol.setBarcodeErr(status[6]); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 读取PLC故障信息 |
| | | */ |
| | | private void readPlcAlarms(List<Integer> staNos, int staNoSize) { |
| | | OperateResultExOne<byte[]> result = siemensS7Net.Read( |
| | | PlcAlarmDefinition.ALL.buildAddress(), |
| | | (short) (staNoSize * PlcAlarmDefinition.ALL.getByteLength())); |
| | | |
| | | if (!result.IsSuccess) { |
| | | log.warn("读取PLC故障信息失败 [id:{}]", slave.getId()); |
| | | return; |
| | | } |
| | | |
| | | byte[] content = result.Content; |
| | | for (int i = 0; i < staNoSize; i++) { |
| | | Integer siteId = staNos.get(i); |
| | | StaProtocol staProtocol = station.get(siteId); |
| | | if (staProtocol == null) { |
| | | continue; |
| | | } |
| | | |
| | | boolean[] status = siemensS7Net.getByteTransform().TransBool( |
| | | content, i * PlcAlarmDefinition.ALL.getByteLength(), 1); |
| | | |
| | | staProtocol.setBreakerErr(status[0]); |
| | | staProtocol.setInfraredErr(status[1]); |
| | | staProtocol.setOutTimeErr(status[2]); |
| | | staProtocol.setSeizeSeatErr(status[3]); |
| | | staProtocol.setWrkYgoodsN(status[4]); |
| | | staProtocol.setInverterErr(status[5]); |
| | | staProtocol.setContactErr(status[6]); |
| | | staProtocol.setUpcontactErr(status[7]); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 按需更新数据库(降低更新频率) |
| | | */ |
| | | private void updateDatabaseIfNeeded() { |
| | | long currentTime = System.currentTimeMillis(); |
| | | if (currentTime - lastDbUpdateTime < DB_UPDATE_INTERVAL_MS) { |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | List<Integer> staNos = slave.getStaNos(); |
| | | List<Devp> devps = new ArrayList<>(staNos.size()); |
| | | for (Integer siteId : staNos) { |
| | | StaProtocol staProtocol = station.get(siteId); |
| | | if (staProtocol != null) { |
| | | devps.add(staProtocol.toSqlModel()); |
| | | } |
| | | } |
| | | |
| | | if (devps.isEmpty()) { |
| | | return; |
| | | } |
| | | |
| | | DevpService devpService = SpringContextUtil.getBean(DevpService.class); |
| | | if (devpService != null) { |
| | | devpService.updateBatchByDevpNo(devps); |
| | | lastDbUpdateTime = currentTime; |
| | | log.debug("批量更新数据库成功 [id:{}] [count:{}]", slave.getId(), devps.size()); |
| | | } else { |
| | | log.error("DevpService未找到,无法更新数据库 [id:{}]", slave.getId()); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("更新数据库数据失败 [id:{}]", slave.getId(), e); |
| | | News.error("SiemensDevp - 3 - 更新数据库数据失败 ===>> [id:{}]", slave.getId()); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |