From c42614978ff12013a1eabebd0289b27169a5784f Mon Sep 17 00:00:00 2001 From: liurunyu <lry9898@163.com> Date: 星期二, 06 五月 2025 17:25:56 +0800 Subject: [PATCH] 1、实现万功能token(0000-0000-1234-9876-5); 2、web端单独实现命令结果等待器,并相应修改相关部分; 3、web端实现透传命令; 4、修改一些不当注释; 5、优化一些代码。 --- pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/upgrade/UpgradeTask.java | 451 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 451 insertions(+), 0 deletions(-) diff --git a/pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/upgrade/UpgradeTask.java b/pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/upgrade/UpgradeTask.java new file mode 100644 index 0000000..7c61420 --- /dev/null +++ b/pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/upgrade/UpgradeTask.java @@ -0,0 +1,451 @@ +package com.dy.rtuMw.server.upgrade; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.dy.common.mw.protocol.rtuState.RtuStatus; +import com.dy.common.softUpgrade.parse.HexFileParse; +import com.dy.common.softUpgrade.state.UpgradeRtu; +import com.dy.common.softUpgrade.state.UpgradeState; +import com.dy.common.softUpgrade.state.UpgradeTaskVo; +import com.dy.common.util.Callback; +import com.dy.common.util.DateTime; +import com.dy.rtuMw.server.forTcp.RtuStatusDealer; +import lombok.Data; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * @Author: liurunyu + * @Date: 2024/11/4 14:52 + * @Description + */ +@Data +public class UpgradeTask { + + private static final Logger log = LogManager.getLogger(UpgradeTask.class.getName()); + + protected static final String TaskOverType_Natural = "鑷劧" ; + protected static final String TaskOverType_Force = "寮哄埗" ; + + @JSONField(serialize = false) + protected Integer failTryTimes ;//鍗囩骇澶辫触鍚庯紝閲嶆柊鍋胯瘯鍗囩骇娆℃暟锛�0琛ㄧず涓嶉噸鏂板伩璇曞崌绾� + @JSONField(serialize = false) + protected Integer ugMaxRtuSameTime ;//鍚屾椂鍗囩骇RTU鏈�澶т釜鏁� + @JSONField(serialize = false) + private Boolean openNoUpgrade ;//闃�寮�锛堟车寮�锛変笉鎵ц鍗囩骇 + @JSONField(serialize = false) + private Integer lastOpenMaxGoOn ;//闃�寮�锛堟车寮�锛夌姸鎬佽缃互鏉ユ寔缁渶闀挎椂闂达紙绉掗挓锛夛紝瓒呰繃杩欎釜鏃堕棿璁や负鐘舵�佹棤鏁堬紙杩欎釜鏃堕暱鍙栧喅浜庡伐浣滄姤闂撮殧锛� + + public String setupDt ;//璁剧疆鏃堕棿(yyyy-mm-dd HH:MM:SS) + @JSONField(serialize = false) + private Long setupDtLong ;//璁剧疆鏃堕棿 + + public UpgradeTaskVo taskVo ;//鍗囩骇浠诲姟鍊煎璞� + + @JSONField(serialize = false) + protected byte[][] softFileDataGrp ;//浠�512瀛楄妭涓哄崟浣嶆妸鍗囩骇绋嬪簭鏁版嵁鍒嗙粍 + + @JSONField(serialize = false) + protected ConcurrentHashMap<String, UpgradeRtu> upgradeRtus;//鍗囩骇鐘舵�� + + public boolean taskIsOver = false ;//浠诲姟鏄惁瀹屾垚 + public String taskOverType = "" ;//浠诲姟瀹屾垚鏂瑰紡锛堣嚜鐒讹紝寮哄埗锛� + public String taskOverDt = "" ;//浠诲姟瀹屾垚鏃堕棿(yyyy-mm-dd HH:MM:SS) + + /////////////////////////////////////////////////// + //浠ヤ笅鍐呴儴鎺у埗鐢� + @JSONField(serialize = false) + protected int curUgRunningRtuTotal = 0 ;//褰撳墠姝e湪鍗囩骇鐨凴TU涓暟 + + public UpgradeTask() { + this.curUgRunningRtuTotal = 0 ; + } + /** + * 鍒濆鍖栭厤缃俊鎭� + */ + public void initOption(Boolean openNoUpgrade, + Integer lastOpenMaxGoOn, + Integer failTryTimes, + Integer ugMaxRtuSameTime) { + this.openNoUpgrade = openNoUpgrade; + this.lastOpenMaxGoOn = lastOpenMaxGoOn; + this.failTryTimes = failTryTimes; + this.ugMaxRtuSameTime = ugMaxRtuSameTime; + } + /** + * 璁剧疆鍗囩骇浠诲姟 + * @param taskVo UpgradeTaskVo 鍗囩骇浠诲姟瀵硅薄 + * @throws Exception + */ + public void setTask(UpgradeTaskVo taskVo) throws Exception { + if(taskVo.id == null || taskVo.id.trim().length() == 0){ + throw new Exception("鍗囩骇浠诲姟id蹇呴』鎻愪緵") ; + } + if(taskVo.softFileName == null || taskVo.softFileName.trim().length() == 0){ + throw new Exception("鍗囩骇杞欢锛坔ex锛夋枃浠跺悕绉板繀椤绘彁渚�") ; + } + if(taskVo.softStoreAddr == null || taskVo.softStoreAddr.trim().length() != 8){ + throw new Exception("鍗囩骇绋嬪簭瀛樻斁鍦板潃涓嶅悎娉曪紝蹇呴』鏄�8瀛楃锛堝崄鍏繘鍒讹級鐨勫瓧绗︿覆") ; + } + if(taskVo.softStartAddr == null || taskVo.softStartAddr.trim().length() != 8){ + throw new Exception("绋嬪簭瑕嗙洊璧峰鍦板潃涓嶅悎娉曪紝蹇呴』鏄�8瀛楃锛堝崄鍏繘鍒讹級鐨勫瓧绗︿覆") ; + } + if(taskVo.softFileData64 == null || taskVo.softFileData64.trim().length() == 0){ + throw new Exception("鍗囩骇绋嬪簭鍐呭蹇呴』鎻愪緵") ; + } + if(taskVo.softBytesCalculate == null){ + throw new Exception("鍏紡璁$畻鍗囩骇绋嬪簭鏈夋晥搴忓瓧鑺傛暟蹇呴』鎻愪緵") ; + } + if(taskVo.softByteSrc16 == null){ + throw new Exception("鏈夋晥鍗囩骇绋嬪簭瀛楄妭鏁癈RC16鏍¢獙鍊煎繀椤绘彁渚�") ; + } + if(taskVo.rtuAddrList == null || taskVo.rtuAddrList.size() <= 0){ + throw new Exception("鍗囩骇璁惧RTU鍦板潃蹇呴』鎻愪緵") ; + } + if(taskVo.callbackWebUrl == null || taskVo.callbackWebUrl.trim().equals("")){ + throw new Exception("鍥炶皟缃戝潃蹇呴』鎻愪緵") ; + } + this.setupDt = DateTime.yyyy_MM_dd_HH_mm_ss() ; + this.setupDtLong = System.currentTimeMillis() ; + this.taskVo = taskVo ; + + this.upgradeRtus = new ConcurrentHashMap<>(); + if(taskVo.softFileData64 != null && !taskVo.softFileData64.trim().equals("")){ + taskVo.softFileData = Base64.getDecoder().decode(taskVo.softFileData64); + List<byte[]> listBytes = new HexFileParse().splitBytesByUnit512(taskVo.softFileData); + this.softFileDataGrp = listBytes.toArray(new byte[0][]); + try{ + for(String rtuAddr : this.taskVo.rtuAddrList){ + //姝ゆ椂鐘舵�佽缃垚绂荤嚎鐘舵�� + UpgradeRtuDev ugRtu = new UpgradeRtuDev(this.taskVo, this.failTryTimes, rtuAddr, this.softFileDataGrp.length, UpgradeRtuDev.STATE_OFFLINE) ; + this.upgradeRtus.put(rtuAddr, ugRtu) ; + } + }catch (Exception e){ + log.error(e); + } + } + } + /** + * RTU鏈変笂琛屾暟鎹簡锛岃Е鍙戜笅鍙戝崌绾ф暟鎹� + * @param rtuAddr + * @param code + * @param callbackCom + */ + public void trigger(String rtuAddr, String code, String protocolName, Short protocolVersion, Callback callbackCom, Object ...objects){ + if(this.upgradeRtus != null && this.upgradeRtus.size() > 0 + && this.taskVo.rtuAddrList != null && this.taskVo.rtuAddrList.size() > 0){ + UpgradeRtu ugRtu = this.upgradeRtus.get(rtuAddr) ; + if(ugRtu == null){ + //鏍规嵁鏂规硶setTask鐨勯�昏緫锛屽彧瑕丷TU鍦ㄥ崌绾т箣鍒楋紝姝ゅugRtuState涓�瀹氫笉涓簄ull + //涓轰繚闄╋紝瀹炵幇涓嬮潰閫昏緫 + if(taskVo.rtuAddrList.contains(rtuAddr)){ + ugRtu = new UpgradeRtuDev(this.taskVo, this.failTryTimes, rtuAddr, this.taskVo.softFileData.length) ; + upgradeRtus.put(rtuAddr, ugRtu) ; + }else{ + //rtu涓嶅湪鍗囩骇涔嬪垪 + return ; + } + }else{ + if(ugRtu.isOver){ + //褰撳墠RTU宸茬粡鍗囩骇瀹屾垚锛屾棤闇�鍐嶅崌绾� + return; + }else{ + if(this.openNoUpgrade){ + //棣栧厛鍒ゆ柇鏄惁鏄榾闂ㄦ墦寮�鐘舵�� + RtuStatus rtuStatus = RtuStatusDealer.oneStatus(rtuAddr) ; + if(rtuStatus != null + && rtuStatus.valveOpenTrueCloseFalse != null + && rtuStatus.valveOpenTrueCloseFalse.booleanValue() == true + && rtuStatus.valveStatusLastTimeStamp != null){ + //鏈夌姸鎬侊紝骞朵笖鏄榾寮�锛堟车寮�锛� + Long now = System.currentTimeMillis() ; + Long gap = now - rtuStatus.valveStatusLastTimeStamp ; + if(gap < this.lastOpenMaxGoOn){ + //杩欐椂閲囩撼闃�闂ㄦ墦寮�鐘舵�侊紝杩涜�屼笉鑳藉崌绾� + ugRtu.isOver = true ; + ugRtu.state = UpgradeRtu.STATE_FAILOPEN ; + return; + } + } + } + + if(UpgradeUnit.confVo.ugMaxRtuAtOnce > 0){ + //璁剧疆浜嗗悓鏃跺崌绾х殑RTU鏈�澶ф暟閲忕殑闄愬埗 + if(ugRtu.state == UpgradeRtuDev.STATE_OFFLINE){ + //鍒濆鎬侊紝璇存槑鍗囩骇浠诲姟璁剧疆浠ユ潵锛岃RTU绗竴娆′笂琛屾暟鎹� + if(this.curUgRunningRtuTotal <= UpgradeUnit.confVo.ugMaxRtuAtOnce){ + //褰撳墠姝e湪鍗囩骇鐨凴TU鏁伴噺杩樻湭鍙楅檺 + ugRtu.trigger(code, protocolName, protocolVersion, this.softFileDataGrp, callbackCom, objects) ; + }else{ + //鍚屾椂鍗囩骇鐨凴TU鏁伴噺鍙楅檺锛岀瓑寰呬笅娆℃満浼� + //浣嗗厛琛ㄦ槑涓�涓嬬姸鎬� + ugRtu.state = UpgradeRtuDev.STATE_UNSTART ; + return ; + } + }else if(ugRtu.state == UpgradeRtuDev.STATE_UNSTART){ + //鏍规嵁涓婇潰閫昏緫锛� 璇存槑蹇呯劧鍦ㄧ嚎浜� + if(this.curUgRunningRtuTotal <= UpgradeUnit.confVo.ugMaxRtuAtOnce){ + //褰撳墠姝e湪鍗囩骇鐨凴TU鏁伴噺杩樻湭鍙楅檺 + ugRtu.trigger(code, protocolName, protocolVersion, this.softFileDataGrp, callbackCom, objects) ; + }else{ + //鍚屾椂鍗囩骇鐨凴TU鏁伴噺鍙楅檺锛岀瓑寰呬笅娆℃満浼� + return ; + } + }else{ + //RTU宸茬粡澶勪簬鍗囩骇杩囩▼涓� + ugRtu.trigger(code, protocolName, protocolVersion, this.softFileDataGrp, callbackCom, objects) ; + } + }else{ + //娌℃湁璁剧疆鍚屾椂鍗囩骇鐨凴TU鏈�澶ф暟閲忕殑闄愬埗 + ugRtu.trigger(code, protocolName, protocolVersion, this.softFileDataGrp, callbackCom, objects) ; + } + } + } + } + } + /** + * 寮哄埗缁撴潫鍗囩骇浠诲姟 + */ + public void forceOver(){ + if(!this.taskIsOver){ + this.taskIsOver = true ;//寮哄埗璁剧疆浠诲姟瀹屾垚 + this.taskOverType = TaskOverType_Force ;//浠诲姟瀹屾垚鏂瑰紡锛堣嚜鐒讹紝寮哄埗锛� + this.taskOverDt = DateTime.yyyy_MM_dd_HH_mm_ss() ;//浠诲姟瀹屾垚鏃堕棿(yyyy-mm-dd HH:MM:SS) + //this.taskVo.rtuAddrList.clear(); + //this.upgradeState.clear(); + } + } + + + /** + * 褰撳墠鍗囩骇鐘舵�� + * @return + */ + public UpgradeState currentUpgradeState() { + UpgradeState state = new UpgradeState() ; + if(this.taskVo.rtuAddrList != null && this.taskVo.rtuAddrList.size() > 0){ + state.rtuTotal = this.taskVo.rtuAddrList.size() ; + if(this.upgradeRtus != null && this.upgradeRtus.size() > 0){ + AtomicBoolean hasRunning = new AtomicBoolean(false); + this.upgradeRtus.values().forEach(info ->{ + if(info.state == UpgradeRtu.STATE_OFFLINE){ + state.offLineTotal++ ; + }else 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++; + }else if(info.state == UpgradeRtu.STATE_FAILONE) { + state.dieOneTotal++; + if(info.isOver){ + state.failTotal++; + } + }else if(info.state == UpgradeRtu.STATE_FAIL) { + state.dieMultiTotal++; + if(info.isOver) { + state.failTotal++; + } + }else if(info.state == UpgradeRtu.STATE_FAILOFFLINE) { + state.failTotal++; + state.failOffTotal++; + }else if(info.state == UpgradeRtu.STATE_FAILOPEN) { + state.failTotal++; + state.failOpenTotal++; + } + if(info.isOver){ + state.overTotal++; + }else{ + hasRunning.set(true); + } + }); + if(!hasRunning.get()){ + state.allOver = true ; + }else{ + state.allOver = false ; + } + } + } + return state ; + } + + /** + * Rtu鍗囩骇淇℃伅 + * @param rtuAddr + * @return + */ + public UpgradeRtu upgradeInfos(String rtuAddr){ + return this.upgradeRtus.get(rtuAddr) ; + } + + /** + * 涓�浜汻tu鍗囩骇淇℃伅 + * @param rtuAddrList + * @return + */ + public List<UpgradeRtu> upgradeInfos(List<String> rtuAddrList){ + List<UpgradeRtu> list = new ArrayList<>() ; + for(String rtuAddr : rtuAddrList){ + UpgradeRtu info = this.upgradeRtus.get(rtuAddr) ; + if(info != null){ + list.add(info) ; + } + } + return list ; + } + /** + * 鍏ㄩ儴Rtu鍗囩骇淇℃伅 + * @return + */ + public List<UpgradeRtu> upgradeInfoAll(){ + if(this.upgradeRtus != null && this.upgradeRtus.size() > 0){ + return this.upgradeRtus.values().stream().toList(); + }else{ + return null ; + } + } + + /////////////////////////////////////////////////////////// + // + // 浠ヤ笅鏂规硶涓哄唴閮ㄦ湇鍔★紝涓嶅澶栨彁渚涙湇鍔� + // + /////////////////////////////////////////////////////////// + + /** + * 闃�寮�锛堟车寮�锛変笉鍗囩骇澶勭悊 + */ + protected void openNoUpgrade(){ + if(this.upgradeRtus != null && this.upgradeRtus.size() > 0){ + Map<String, RtuStatus> rsAllMap = RtuStatusDealer.allStatus() ; + Long now = System.currentTimeMillis() ; + this.upgradeRtus.values().stream().forEach(a -> { + RtuStatus rs = rsAllMap.get(a.rtuAddr) ; + if(rs != null + && rs.valveOpenTrueCloseFalse != null && rs.valveOpenTrueCloseFalse.booleanValue() == true + && rs.valveStatusLastTimeStamp != null){ + //鏈夌姸鎬侊紝骞朵笖鏄榾寮�锛堟车寮�锛� + Long gap = now - rs.valveStatusLastTimeStamp ; + if(gap < this.lastOpenMaxGoOn){ + //杩欐椂閲囩撼闃�闂ㄦ墦寮�鐘舵�佷笉鑳藉崌绾� + a.isOver = true ; + a.state = UpgradeRtu.STATE_FAILOPEN ; + } + } + }); + } + } + /** + * 鍒ゆ柇鏄惁娌$敤浠讳綍涓�涓猂TU杩涜杩囧崌绾э紝鑰屼笖瓒呰繃浜嗘椂闄� + * @return -1:鏃犱竴RTU鍗囩骇涓旇秴鏃讹紝0锛氭棤RTU鍗囩骇浣嗘湭瓒呮椂绛夊緟锛�1鏈塕TU鍗囩骇姝e父鎵ц + */ + protected int countNoOneRtuUpgradeInDuration(){ + if(this.upgradeRtus == null || upgradeRtus.size() == 0){ + //褰撳墠娌℃湁浠讳綍涓�涓澶囪繘琛岃繃鍗囩骇 + Long now = System.currentTimeMillis() ; + if(now - this.setupDtLong > UpgradeUnit.confVo.noOneRtuUpgradeMaxDuration){ + return -1 ; + } + }else{ + Collection<UpgradeRtu> col = this.upgradeRtus.values() ; + for(UpgradeRtu info : col){ + if(info.currentPackage > 0){ + //褰撳墠鏈夎澶囪繘琛岃繃鍗囩骇 + return 1 ; + } + } + Long now = System.currentTimeMillis() ; + if(now - this.setupDtLong > UpgradeUnit.confVo.noOneRtuUpgradeMaxDuration){ + return -1 ; + } + } + return 0 ; + } + + /** + * 缁熻褰撳墠姝e湪鍗囩骇鐨凴TU鏁伴噺锛屼负鍚屾椂鍗囩骇鏁伴噺闄愬埗鍋氬噯澶� + */ + protected int countRunningRtuCount(){ + int runningTotal = 0 ; + Collection<UpgradeRtu> col = this.upgradeRtus.values() ; + for(UpgradeRtu info : col){ + if(info.state == UpgradeRtu.STATE_RUNNING){ + runningTotal ++ ; + } + } + return this.curUgRunningRtuTotal = runningTotal ; + } + + /** + * 缁熻闇�瑕佸崌绾т絾褰撳墠绂荤嚎RTU鐨勬儏鍐碉紝瓒呰繃鏃堕檺鐨勮澶囦负鍗囩骇瀹屾垚 + * @return -1:娌℃湁瓒呮椂锛�0瓒呮椂浜嗕笖鏃犲洜绂荤嚎琚己鍒惰缃崌绾у畬鎴愮殑RTU锛�>0绂荤嚎琚己鍒惰缃崌绾у畬鎴愮殑RTU鏁伴噺 + */ + protected int countOffRtuAndSetIfOver() { + Long now = System.currentTimeMillis() ; + if(now - this.setupDtLong > UpgradeUnit.confVo.rtuOffLineWaitDuration){ + //rtu绂荤嚎锛岀瓑寰呭叾鍗囩骇鐨勬椂闀�(姣)锛岃秴杩囬厤缃殑鏈�澶ф椂闀匡紝璁剧疆鍏跺崌绾уけ璐ワ紝涓旇缃崌绾т换鍔″畬鎴� + int count = 0 ; + if (this.taskVo.rtuAddrList != null && this.taskVo.rtuAddrList.size() > 0) { + Collection<UpgradeRtu> col = this.upgradeRtus.values() ; + for(UpgradeRtu info : col){ + if(info.state == UpgradeRtu.STATE_OFFLINE){ + info.isOver = true ; + info.state = UpgradeRtu.STATE_FAILOFFLINE ; + count ++ ; + } + } + } + return count ; + }else{ + return -1 ; + } + } + + /** + * 缁熻:宸茬粡杩涘崌绾т絾RTU鍙堣繘鍏ュ仠姝㈠崌绾у彂鍛嗙姸鎬侊紝瓒呰繃涓�瀹氭椂闄愶紝璁剧疆璁惧涓�鍖呮鎴栧鍖呮锛屽苟璁剧疆涓哄崌绾у畬鎴� + * @return -1:娌℃湁瓒呮椂锛�0瓒呮椂浜嗕笖鏃犲洜绂荤嚎琚己鍒惰缃崌绾у畬鎴愮殑RTU锛�>0绂荤嚎琚己鍒惰缃崌绾у畬鎴愮殑RTU鏁伴噺 + */ + protected int countRunningIdleRtuAndSetIfOver() { + Long now = System.currentTimeMillis() ; + int count = -1 ; + if(now - this.setupDtLong > UpgradeUnit.confVo.rtuOffLineWaitDuration){ + //璁剧疆涓婂彞锛岄槻姝㈤绻佽繘鍏ヤ笅闈㈣鍙ヨ繘琛岃绠� + if (this.taskVo.rtuAddrList != null && this.taskVo.rtuAddrList.size() > 0) { + Collection<UpgradeRtu> col = this.upgradeRtus.values() ; + for(UpgradeRtu info : col){ + if(info.state == UpgradeRtu.STATE_RUNNING && info.isOver == false){ + //鍗囩骇涓紝浣嗘湭鍗囩骇瀹屾垚 + if(now - info.lastDownDtAt > UpgradeUnit.confVo.runningAndIdleDuration){ + if(info.currentPackage <= 1){ + //涓�鍖呮 + info.state = UpgradeRtu.STATE_FAILONE ; + }else{ + //澶氬寘姝� + info.state = UpgradeRtu.STATE_FAIL ; + } + info.isOver = true ; + count ++ ; + } + } + } + } + } + return count ; + } + /** + * 缁熻鏄惁鍗囩骇鍏ㄩ儴缁撴潫 + */ + protected boolean countIsAllOver() { + if (this.taskVo.rtuAddrList != null && this.taskVo.rtuAddrList.size() > 0) { + Collection<UpgradeRtu> col = this.upgradeRtus.values() ; + for(UpgradeRtu info : col){ + if(info.isOver == false){ + return false ; + } + } + } + return true ; + } +} -- Gitblit v1.8.0