liurunyu
2024-11-08 04779efe2410fb0df1ff983b26384d56471b85cf
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
package com.dy.rtuMw.server.upgrade;
 
import com.alibaba.fastjson2.annotation.JSONField;
import com.dy.common.softUpgrade.parse.HexFileParse;
import com.dy.common.softUpgrade.parse.HexFileVo;
import com.dy.common.util.Callback;
import com.dy.common.util.DateTime;
import lombok.Data;
 
import java.util.*;
 
/**
 * @Author: liurunyu
 * @Date: 2024/11/4 14:52
 * @Description
 */
@Data
public class UpgradeTask {
 
    @JSONField(serialize = false)
    protected Integer failTryTimes ;//升级失败后,重新偿试升级次数,0表示不重新偿试升级
    @JSONField(serialize = false)
    protected Integer ugMaxRtuSameTime ;//同时升级RTU最大个数
 
    public String setupDt ;//设置时间(yyyy-mm-dd HH:MM:SS)
 
    public String softFileName ;//升级软件(hex)文件名称
    public String softStoreAddr ;//升级程序存放地址(4字节,8字符HEX字符串),升级程序在FLASH中存放地址
    public String softStartAddr ;//程序覆盖起始地址(4字节,8字符HEX字符串),被刷新程序的起始地址高字节在前 ,低字节在后
 
    @JSONField(serialize = false)
    public byte[][] softData ;//升级程序数据(每包数据是512字节)
    @JSONField(serialize = false)
    public int softByteSrc16;//升级程序校验码 CRC16
 
    public int softBytesCalculate;//升级程序字节数(按公式计算)
 
    public List<String> rtuAddrList ;//需要升级的RTU地址集合
 
    @JSONField(serialize = false)
    public Map<String, UpgradeRtu> upgradeState ;//升级状态
 
    public UpgradeTask() {
    }
    /**
     *  初始化配置信息
     */
    public void initOption(Integer failTryTimes, Integer ugMaxRtuSameTime) {
        this.failTryTimes = failTryTimes;
        this.ugMaxRtuSameTime = ugMaxRtuSameTime;
    }
    /**
     * 设置升级任务
     * @param softFileName 升级程序文件名
     * @param softStoreAddr 升级程序存放地址
     * @param softStartAddr 程序覆盖起始地址
     * @param softFileData 升级程序字节数组
     * @param softBytesCalculate 升级程序字节数(按公式计算)
     * @param rtuAddrList 升级RTU
     * @throws Exception
     */
    public void setTask(String softFileName,
                       String softStoreAddr,
                       String softStartAddr,
                       byte[] softFileData,
                       Integer softBytesCalculate,
                       List<String> rtuAddrList) throws Exception {
        if(softFileName == null || softFileName.trim().length() == 0){
            throw new Exception("升级软件(hex)文件名称必须提供") ;
        }
        if(softStoreAddr == null || softStoreAddr.trim().length() != 8){
            throw new Exception("升级程序存放地址不合法,必须是8字符(十六进制)的字符串") ;
        }
        if(softStartAddr == null || softStartAddr.trim().length() != 8){
            throw new Exception("程序覆盖起始地址不合法,必须是8字符(十六进制)的字符串") ;
        }
        if(softFileData == null || softFileData.length <= 0){
            throw new Exception("升级程序内容必须提供") ;
        }
        if(rtuAddrList == null || rtuAddrList.size() <= 0){
            throw new Exception("升级设备RTU地址必须提供") ;
        }
        this.setupDt = DateTime.yyyy_MM_dd_HH_mm_ss() ;
        this.softFileName = softFileName;
        this.softStoreAddr = softStoreAddr;
        this.softStartAddr = softStartAddr;
        this.softBytesCalculate = softBytesCalculate;
        this.rtuAddrList = rtuAddrList;
 
        this.upgradeState = new HashMap<>();
        if(softFileData != null && softFileData.length >0){
            HexFileVo vo = new HexFileParse().doParse(softFileData);
            this.softData = vo.listByte512.toArray(new byte[0][]);
            this.softByteSrc16 = vo.bytesCrc16 ;
        }
    }
    /**
     * RTU有上行数据了,触发下发升级数据
     * @param rtuAddr
     * @param code
     * @param callback
     */
    public void trigger(String rtuAddr, String code, String protocolName, Short protocolVersion, Callback callback){
        if(upgradeState != null && upgradeState.size() > 0
                && rtuAddrList != null && rtuAddrList.size() > 0){
            UpgradeRtu info = upgradeState.get(rtuAddr) ;
            if(info == null){
                if(rtuAddrList.contains(rtuAddr)){
                    info = new UpgradeRtu(this, rtuAddr, softData.length) ;
                    upgradeState.put(rtuAddr, info) ;
                }else{
                    //rtu不在升级之列
                    return ;
                }
            }
            if(info != null){
                info.trigger(code, protocolName, protocolVersion, this.softData, callback) ;
            }
        }
    }
 
    /**
     * 强制结束升级任务
     */
    public void forceOver(){
        this.rtuAddrList.clear();
        this.upgradeState.clear();
    }
 
    /**
     * 升级任务是否完成
     * @return
     */
    public boolean isOver() {
        boolean isOver = true ;
        if(upgradeState != null && upgradeState.size() > 0){
            Collection<UpgradeRtu> col = upgradeState.values() ;
            for(UpgradeRtu info : col){
                if(info.state == UpgradeRtu.STATE_UNSTART){
                    isOver = false ;
                    break ;
                }else if(info.state == UpgradeRtu.STATE_RUNNING){
                    isOver = false ;
                    break ;
                }
            }
        }
        return isOver ;
    }
 
    /**
     * 当前升级状态
     * @return
     */
    public UpgradeState currentUpgradeState() {
        UpgradeState state = new UpgradeState() ;
        if(rtuAddrList != null && rtuAddrList.size() > 0){
            state.rtuTotal = rtuAddrList.size() ;
            if(upgradeState != null && upgradeState.size() > 0){
                Collection<UpgradeRtu> col = upgradeState.values() ;
                for(UpgradeRtu info : col){
                    if(info.state == UpgradeRtu.STATE_UNSTART){
                        state.unStartTotal ++ ;
                    }else if(info.state == UpgradeRtu.STATE_RUNNING){
                        state.runningTotal ++ ;
                    }else if(info.state == UpgradeRtu.STATE_SUCCESS) {
                        state.successTotal++;
                        state.overTotal++;
                    }else if(info.state == UpgradeRtu.STATE_FAILONE) {
                        state.failOneTotal++;
                        state.failTotal++;
                        state.overTotal++;
                    }else if(info.state == UpgradeRtu.STATE_FAIL) {
                        state.failTotal++;
                        state.overTotal++;
                    }
                }
            }
        }
        return state ;
    }
 
    /**
     * Rtu升级信息
     * @param rtuAddr
     * @return
    */
    public UpgradeRtu upgradeInfos(String rtuAddr){
        return upgradeState.get(rtuAddr) ;
    }
 
    /**
     * Rtu升级信息
     * @param rtuAddrList
     * @return
     */
    public List<UpgradeRtu> upgradeInfos(List<String> rtuAddrList){
        List<UpgradeRtu> list = new ArrayList<>() ;
        for(String rtuAddr : rtuAddrList){
            UpgradeRtu info = upgradeState.get(rtuAddr) ;
            if(info != null){
                list.add(info) ;
            }
        }
        return list ;
    }
 
}