1
zhang
昨天 6e7005a9c8f0e9c21f2d3a4d77a779381e859ac3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package com.zy.acs.conveyor.core.service;
 
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import com.alibaba.fastjson.JSON;
import com.zy.acs.common.utils.News;
import com.zy.acs.conveyor.core.constant.PlcConstant;
import com.zy.acs.conveyor.core.constant.TaskField;
import com.zy.acs.conveyor.core.model.StaProtocol;
import com.zy.acs.conveyor.core.properties.DevpSlave;
import com.zy.acs.conveyor.core.properties.OutputQueue;
import com.zy.acs.conveyor.core.properties.SlaveProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import java.text.MessageFormat;
import java.util.List;
 
 
@Slf4j
@Service
public class Snap7Service {
 
    @Autowired
    private SlaveProperties slaveProperties;
 
    @Autowired
    private DevpS7Service devpS7Service;
 
 
    private static final int WRITE_RETRY_MAX = 5;
 
    private static final int WRITE_RETRY_INTERVAL_MS = 200;
 
    public void read(StaProtocol staProtocol, SiemensS7Net siemensS7Net) {
 
    }
 
 
    public void write(StaProtocol staProtocol) throws InterruptedException {
        if (staProtocol == null) {
            log.warn("写入数据为空,跳过 [id:{}]", JSON.toJSONString(staProtocol));
            return;
        }
 
        SiemensS7Net siemensS7Net = devpS7Service.get(staProtocol.getPlcId());
        if (siemensS7Net == null) {
            log.error("PLC未连接,无法写入 [id:{}]", JSON.toJSONString(staProtocol));
            return;
        }
 
        List<DevpSlave> devp = slaveProperties.getDevp();
        DevpSlave devpSlave = devp.stream().filter(slave -> slave.getId().equals(staProtocol.getPlcId())).findFirst().orElse(null);
        if (devpSlave == null) {
            log.error("PLC未配置,无法写入 [id:{}]", JSON.toJSONString(staProtocol));
            return;
        }
        int index = devpSlave.getStaNos().indexOf(staProtocol.getSiteId());
        if (index < 0) {
            log.error("站点编号不存在于配置中 [id:{}] [siteId:{}]", staProtocol.getPlcId(), staProtocol.getSiteId());
            return;
        }
 
        int baseOffset = index * TaskField.ALL.getByteLength();
        String workNoAddr = TaskField.TASK_NUMBER.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION
                + (baseOffset + TaskField.TASK_NUMBER.getOffset());
        String destStaAddr = TaskField.DEST_STATION.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION
                + (baseOffset + TaskField.DEST_STATION.getOffset());
 
        // 任务下发重试机制
        int writeCount = 0;
        boolean success = false;
 
        while (writeCount < WRITE_RETRY_MAX) {
            OperateResult writeResult = siemensS7Net.Write(workNoAddr, staProtocol.getWorkNo().shortValue());
            Thread.sleep(WRITE_RETRY_INTERVAL_MS);
 
            OperateResult writeResult1 = siemensS7Net.Write(destStaAddr, staProtocol.getStaNo().shortValue());
 
            if (writeResult.IsSuccess && writeResult1.IsSuccess) {
                log.info("写入输送线命令成功 [id:{}] [siteId:{}] [workNo:{}] [destSta:{}] [retry:{}]",
                        staProtocol.getPlcId(), staProtocol.getSiteId(), staProtocol.getWorkNo(),
                        staProtocol.getStaNo(), writeCount);
                OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线命令成功。输送线plc编号={1},站点数据={2}",
                        staProtocol.getPlcId(), JSON.toJSON(staProtocol)));
                success = true;
                break;
            }
 
            writeCount++;
            log.error("写入输送线命令失败 [id:{}] [siteId:{}] [retry:{}] [workErr:{}] [destErr:{}]",
                    staProtocol.getPlcId(), staProtocol.getSiteId(), writeCount,
                    writeResult.Message, writeResult1.Message);
 
            if (writeCount < WRITE_RETRY_MAX) {
                Thread.sleep(WRITE_RETRY_INTERVAL_MS);
            }
        }
 
        if (!success) {
            String errorMsg = MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}",
                    staProtocol.getPlcId(), JSON.toJSON(staProtocol));
            OutputQueue.DEVP.offer(errorMsg);
            News.error("SiemensDevp - 4 - 写入输送线站点数据失败。输送线plc编号={},站点数据={}",
                    staProtocol.getPlcId(), JSON.toJSON(staProtocol));
            log.error(errorMsg);
        }
 
    }
}