From cf160e28026ed1ed8bea82701d66e79a1085c503 Mon Sep 17 00:00:00 2001 From: Riku <risaku@163.com> Date: 星期四, 15 五月 2025 00:24:39 +0800 Subject: [PATCH] 1. 新增走航动态溯源功能 --- src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/DataAnalysisConfig.kt | 4 src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionValueMutation.kt | 3 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRealTimeException.kt | 27 +- src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/RealTimeExceptionAnalysisController.kt | 4 src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionResult.kt | 13 + src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt | 104 ++++++----- src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionSlideAverage.kt | 14 src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionTag.kt | 47 +++++ src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionDataExceed.kt | 5 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/RealTimeAnalysisConfig.kt | 13 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionValueMutation.kt | 19 +- src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionSlideAverage.kt | 214 +++++++++++++++++++++++ src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuousSingle.kt | 16 - src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionSlideAverageTag.kt | 25 ++ src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionAnalysis.kt | 10 + src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionContinuous.kt | 3 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/RealTimeExceptionResult.kt | 6 17 files changed, 426 insertions(+), 101 deletions(-) diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionAnalysis.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionAnalysis.kt index 54e05f4..d43f689 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionAnalysis.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionAnalysis.kt @@ -14,4 +14,14 @@ * 纭畾寮傚父绫诲瀷 */ abstract fun getExceptionType(): ExceptionType + + /** + * 鐢熸垚涓�鏉″紓甯稿垎鏋愮粨鏋� + */ + abstract fun newResult( + start: BaseRealTimeData, + end: BaseRealTimeData?, + factor: FactorFilter.SelectedFactor, + exceptionData: List<BaseRealTimeData>, + ): Y } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt index 0c2e28a..bf4f1d1 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt @@ -1,15 +1,18 @@ package com.flightfeather.uav.biz.dataanalysis import com.flightfeather.uav.biz.FactorFilter +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionTag import com.flightfeather.uav.domain.entity.BaseRealTimeData +import com.flightfeather.uav.lightshare.eunm.ExceptionStatusType import com.flightfeather.uav.socket.eunm.FactorType import java.time.Duration /** * 杩炵画绫诲瀷鐨勫紓甯稿垎鏋愬熀绫�,閫傜敤浜庡綋鍓嶆暟鎹笌鐩搁偦鏁版嵁涔嬮棿鏈夊叧鑱斿叧绯荤殑鎯呭喌 */ -abstract class BaseExceptionContinuous<V : BaseAnalysisConfig, Y : BaseExceptionResult>(config: V) : - BaseExceptionAnalysis<V, Y>(config) { +abstract class BaseExceptionContinuous<T : ExceptionTag, V : BaseAnalysisConfig, Y : BaseExceptionResult>( + config: V, private val tagClz: Class<T> +) : BaseExceptionAnalysis<V, Y>(config) { companion object { // 璁板綍寮傚父鏁版嵁娈垫椂锛屽垎鍒悜璧峰鍓嶅拰鏈熬鍚庨澶栬褰曠殑鏁版嵁涓暟鍋忕Щ閲� @@ -33,17 +36,26 @@ var exceptionData = mutableListOf<BaseRealTimeData>() // 鏄惁瀛樺湪寮傚父 - var existException = false + var exceptionExisted = false - fun refreshAfterCheckResult(data: BaseRealTimeData) { + // 寮傚父缁撴灉鏄惁鍒涘缓 + var exceptionCreated = false + + fun addExceptionData(data: BaseRealTimeData) { + exceptionExisted = true + exceptionData.add(data) + } + + fun refreshWithNextException(data: BaseRealTimeData) { sIndex = eIndex startData = data exceptionData.clear() -// exceptionData.add(data) + exceptionExisted = false + exceptionCreated = false } } - protected val tagMap = mutableMapOf<FactorType, Tag>() + protected val tagMap = mutableMapOf<FactorType, T>() // 璧峰鏁版嵁涓庢湯灏炬暟鎹棿闅� open var durationCount = 1 @@ -71,14 +83,14 @@ * 鍒ゆ柇寮傚父鍑虹幇鐨勮繛缁釜鏁版槸鍚︽弧瓒虫潯浠� * @param tag 寮傚父鏁版嵁瀵硅薄 */ - abstract fun judgeExceptionCount(tag: Tag): Boolean + abstract fun judgeExceptionCount(tag: T): Boolean /** * 寮傚父鏁版嵁鐨勬埅鍙栧垽鏂� * 鏄惁闇�瑕侀檺鍒朵竴缁勫紓甯告暟鎹殑闀垮害 * @return 榛樿涓嶉渶瑕佹埅鍙� */ - open fun needCut(tag: Tag): Boolean { + open fun needCut(tag: T): Boolean { return false } @@ -87,7 +99,7 @@ lastData = null tagMap.clear() config.factorFilter.mainList().forEach { f -> - tagMap[f] = Tag() + tagMap[f] = tagClz.newInstance() } } @@ -101,27 +113,18 @@ // 璧峰鏁版嵁 it.endData = data if (it.startData == null) { - it.refreshAfterCheckResult(data) + it.refreshWithNextException(data) } // 鍒ゆ柇鐩搁偦鏁版嵁鏄惁杩炵画骞朵笖鏄惁婊¤冻寮傚父鍒ゆ柇 if (!isContinue || needCut(it)) { // 鏁版嵁涓嶈繛缁椂锛岃褰曞紓甯告儏鍐� recordException(s, it, data) -// checkResult(s) -// if (it.eIndex - it.sIndex >= durationCount) { -// it.refreshAfterCheckResult(data) -// } } else { if (hasException[f] == true) { - it.existException = true - it.exceptionData.add(data) + it.addExceptionData(data) } else { // 寮傚父涓嶅啀閲嶅鍑虹幇鏃讹紝璁板綍寮傚父鎯呭喌 recordException(s, it, data) -// checkResult(s) -// if (it.eIndex - it.sIndex >= durationCount) { -// it.refreshAfterCheckResult(data) -// } } } } @@ -130,53 +133,62 @@ } override fun onDone() { - checkResult() + checkResult(exceptionStatus = ExceptionStatusType.Ended) } - fun recordException(factor: FactorFilter.SelectedFactor, tag: Tag, data: BaseRealTimeData) { - checkResult(factor) - if (tag.eIndex - tag.sIndex >= durationCount) { - tag.refreshAfterCheckResult(data) - } + /** + * 寮傚父缁撴潫锛岃褰曞紓甯� + */ + fun recordException(factor: FactorFilter.SelectedFactor, tag: T, data: BaseRealTimeData) { + checkResult(factor, ExceptionStatusType.Ended) +// if (tag.eIndex - tag.sIndex >= durationCount) { + tag.refreshWithNextException(data) +// } } /** * 妫�鏌ヨ繛缁紓甯哥粨鏉熸椂锛屾槸鍚︾鍚堝紓甯稿瓨鍌ㄦ潯浠� */ - open fun checkResult(factor: FactorFilter.SelectedFactor? = null) { + open fun checkResult( + factor: FactorFilter.SelectedFactor? = null, + exceptionStatus: ExceptionStatusType = ExceptionStatusType.InProgress + ) { val tag = tagMap[factor?.main] if (factor != null && tag != null) { - if (tag.existException && judgeExceptionCount(tag)) { - onNewException(tag, factor) + if (tag.exceptionExisted && judgeExceptionCount(tag)) { + onNewException(tag, factor, exceptionStatus) } } else { config.factorFilter.selectedList.forEach { f -> val tag1 = tagMap[f.main] ?: return@forEach - if (tag1.existException && judgeExceptionCount(tag1)) { - onNewException(tag1, f) + if (tag1.exceptionExisted && judgeExceptionCount(tag1)) { + onNewException(tag1, f, exceptionStatus) } } } } /** - * 鏂板涓�鏉″紓甯� + * 鏂板鎴栨洿鏂颁竴鏉″紓甯� */ - open fun onNewException(tag:Tag, factor: FactorFilter.SelectedFactor) { - tag.startData?.let { - resultList.add(newResult(it, lastData, factor, tag.exceptionData)) + open fun onNewException(tag: T, factor: FactorFilter.SelectedFactor, exceptionStatus: ExceptionStatusType) { + if (tag.startData == null) return + val ex = newResult(tag.startData!!, lastData, factor, tag.exceptionData) + .apply { status = exceptionStatus.value } + // 寮傚父宸插垱寤烘椂锛屾洿鏂板紓甯镐俊鎭� + if (tag.exceptionCreated) { + // 灏嗘渶鏂扮殑寮傚父鐨刧uid璧嬪�肩粰ex + val lastEx = tag.exceptionResult.last() + ex.guid = lastEx.guid + tag.exceptionResult.removeLast() + tag.exceptionResult.add(ex) } - tag.existException = false + // 寮傚父鏈垱寤烘椂锛屾柊寤哄紓甯镐俊鎭� + else { + tag.exceptionResult.add(ex) +// resultList.add(ex) + tag.exceptionCreated = true + } } - - /** - * 鐢熸垚涓�鏉″紓甯稿垎鏋愮粨鏋� - */ - abstract fun newResult( - start: BaseRealTimeData, - end: BaseRealTimeData?, - factor: FactorFilter.SelectedFactor, - exceptionData: List<BaseRealTimeData>, - ): Y } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuousSingle.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuousSingle.kt index 3912148..6a44390 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuousSingle.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuousSingle.kt @@ -1,12 +1,13 @@ package com.flightfeather.uav.biz.dataanalysis +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionTag import com.flightfeather.uav.domain.entity.BaseRealTimeData /** * 杩炵画绫诲瀷鐨勫紓甯稿垎鏋愬熀绫�,鍖哄埆浜庣埗绫荤殑鍦版柟鍦ㄤ簬姝ょ寮傚父鍙拰鍗曚釜鏁版嵁鏈韩鏈夊叧,涓庣浉閭绘暟鎹棤鍏� */ -abstract class BaseExceptionContinuousSingle<V : BaseAnalysisConfig, Y : BaseExceptionResult>(config: V) : - BaseExceptionContinuous<V, Y>(config) { +abstract class BaseExceptionContinuousSingle<T : ExceptionTag, V : BaseAnalysisConfig, Y : BaseExceptionResult>(config: V, tagClz: Class<T>) : + BaseExceptionContinuous<T, V, Y>(config, tagClz) { override fun onNextData(data: BaseRealTimeData) { val isContinue = isContinuous(lastData, data) @@ -20,20 +21,17 @@ } // 鍒ゆ柇鐩搁偦鏁版嵁鏄惁杩炵画骞朵笖鏄惁婊¤冻寮傚父鍒ゆ柇 if (!isContinue || needCut(it)) { - checkResult(s) - it.refreshAfterCheckResult(data) + recordException(s, it, data) } else { if (hasException[f] == true) { // 淇敼浜嗚捣濮嬫暟鎹殑浣嶇疆,鍙樻洿涓哄嚭鐜板紓甯哥殑璇ュ��,鑰屼笉鏄師鏉ョ殑鍑虹幇寮傚父鏁版嵁鐨勫墠涓�涓�� - if (!it.existException) { + if (!it.exceptionExisted) { it.sIndex = it.eIndex it.startData = data } - it.existException = true - it.exceptionData.add(data) + it.addExceptionData(data) } else { - checkResult(s) - it.refreshAfterCheckResult(data) + recordException(s, it, data) } } } diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionResult.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionResult.kt index 3500ba0..2d9a64e 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionResult.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionResult.kt @@ -1,9 +1,22 @@ package com.flightfeather.uav.biz.dataanalysis +import com.flightfeather.uav.lightshare.eunm.ExceptionStatusType +import java.util.* + /** * 寮傚父缁撴灉鍩虹被 * @date 2025/5/13 * @author feiyu02 */ abstract class BaseExceptionResult { + // 寮傚父缂栧彿 + var guid: String? = null + + // 寮傚父鐨勭姸鎬� + var status: Int = ExceptionStatusType.InProgress.value + + init { + guid = UUID.randomUUID().toString() + } + } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionContinuous.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionContinuous.kt index 3af5a17..a2e4282 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionContinuous.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionContinuous.kt @@ -4,6 +4,7 @@ import com.flightfeather.uav.biz.dataanalysis.BaseExceptionContinuous import com.flightfeather.uav.biz.dataanalysis.model.DataAnalysisConfig import com.flightfeather.uav.biz.dataanalysis.model.ExceptionResult +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionTag import com.flightfeather.uav.domain.entity.BaseRealTimeData /** @@ -12,7 +13,7 @@ * @author feiyu02 */ abstract class ExceptionContinuous(config: DataAnalysisConfig) : - BaseExceptionContinuous<DataAnalysisConfig, ExceptionResult>(config) { + BaseExceptionContinuous<ExceptionTag, DataAnalysisConfig, ExceptionResult>(config, ExceptionTag::class.java) { override fun newResult( start: BaseRealTimeData, diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionDataExceed.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionDataExceed.kt index f57c775..96c4d5e 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionDataExceed.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionDataExceed.kt @@ -4,6 +4,7 @@ import com.flightfeather.uav.biz.dataanalysis.BaseExceptionContinuousSingle import com.flightfeather.uav.biz.dataanalysis.model.DataAnalysisConfig import com.flightfeather.uav.biz.dataanalysis.model.ExceptionResult +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionTag import com.flightfeather.uav.biz.dataanalysis.model.ExceptionType import com.flightfeather.uav.domain.entity.BaseRealTimeData import com.flightfeather.uav.socket.eunm.FactorType @@ -13,7 +14,7 @@ */ @Deprecated("鍘熻秴鏍囧垽瀹氶�昏緫璁惧畾鐨勮秴鏍囧�兼湁婕忔礊锛�") class ExceptionDataExceed(config: DataAnalysisConfig) : - BaseExceptionContinuousSingle<DataAnalysisConfig, ExceptionResult>(config) { + BaseExceptionContinuousSingle<ExceptionTag, DataAnalysisConfig, ExceptionResult>(config, ExceptionTag::class.java) { override fun getExceptionType(): ExceptionType = ExceptionType.TYPE2 @@ -32,7 +33,7 @@ return res } - override fun judgeExceptionCount(tag: Tag): Boolean { + override fun judgeExceptionCount(tag: ExceptionTag): Boolean { return true } diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionSlideAverage.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionSlideAverage.kt index 6ac4ab8..f5f6b8b 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionSlideAverage.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionSlideAverage.kt @@ -44,7 +44,7 @@ var exceptionData = mutableListOf<BaseRealTimeData>() // 鏄惁瀛樺湪寮傚父 - var existException = false + var exceptionExisted = false fun refreshAfterCheckResult(data: BaseRealTimeData) { // 鍒ゆ柇骞舵洿鏂拌捣濮嬬偣浣嶇疆 @@ -100,7 +100,7 @@ if (tempDataList.size == config.changeTrendGroup) { calAvg(f, tempDataList) if (checkSlideAvg(f)) { - it.existException = true + it.exceptionExisted = true it.exceptionData.add(data) } else { checkResult(s) @@ -181,27 +181,27 @@ private fun checkResult(factor: FactorFilter.SelectedFactor? = null) { val tag = tagMap[factor?.main] if (factor != null && tag != null) { - if (tag.existException) { + if (tag.exceptionExisted) { tag.startData?.let { resultList.add(newResult(it, lastData, factor, tag.exceptionData)) } - tag.existException = false + tag.exceptionExisted = false } } else { config.factorFilter.selectedList.forEach { f -> val tag1 = tagMap[f.main] ?: return@forEach - if (tag1.existException) { + if (tag1.exceptionExisted) { tag1.startData?.let { resultList.add(newResult(it, lastData, f, tag1.exceptionData)) } - tag1.existException = false + tag1.exceptionExisted = false } } } } - fun newResult( + override fun newResult( start: BaseRealTimeData, end: BaseRealTimeData?, factor: FactorFilter.SelectedFactor, diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionValueMutation.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionValueMutation.kt index 582223b..082db5e 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionValueMutation.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionValueMutation.kt @@ -1,6 +1,7 @@ package com.flightfeather.uav.biz.dataanalysis.exceptiontype import com.flightfeather.uav.biz.dataanalysis.model.DataAnalysisConfig +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionTag import com.flightfeather.uav.biz.dataanalysis.model.ExceptionType import com.flightfeather.uav.domain.entity.BaseRealTimeData import com.flightfeather.uav.socket.eunm.FactorType @@ -39,7 +40,7 @@ return res } - override fun judgeExceptionCount(tag: Tag): Boolean { + override fun judgeExceptionCount(tag: ExceptionTag): Boolean { // 棣栦釜鏁版嵁娌℃湁鍓嶄竴涓暟鎹弬鐓э紝涓嶇畻寮傚父鍊硷紝鏈�鍚庝竴涓暟鎹槸鍒ゆ柇缁撴潫鐨勬甯稿�硷紝鍥犳寮傚父鏁版嵁涓暟鐨勮绠椾笅鏍囦负sIndex鍜宔Index val sIndex = tag.sIndex val eIndex = tag.eIndex - 1 diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/DataAnalysisConfig.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/DataAnalysisConfig.kt index 165586f..35cf6a5 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/DataAnalysisConfig.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/DataAnalysisConfig.kt @@ -16,10 +16,10 @@ factorFilter: FactorFilter, ) : BaseAnalysisConfig(factorFilter) { // 杩炵画绐佸彉鏁版嵁涓暟 - var mutationNum = 2 + var mutationNum = 3 // 绐佸彉鐜� - var mutationRate = .5 + var mutationRate = .2 // 姹傛粦鍔ㄥ钩鍧囧�肩殑鏁版嵁缁勪釜鏁� var changeTrendGroup = 12 diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionSlideAverageTag.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionSlideAverageTag.kt new file mode 100644 index 0000000..9f755b8 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionSlideAverageTag.kt @@ -0,0 +1,25 @@ +package com.flightfeather.uav.biz.dataanalysis.model + +import com.flightfeather.uav.domain.entity.BaseRealTimeData + +/** + * 婊戝姩骞冲潎鍊肩獊鍙樺紓甯告暟鎹爣绛� + * @date 2025/5/13 + * @author feiyu02 + */ +class ExceptionSlideAverageTag : ExceptionTag() { + + // 鏁版嵁缁勫潎鍊肩殑闆嗗悎 + val avgListReverse = mutableListOf<Pair<Double, Boolean>>() + + fun refreshAfterCheckResult(historyDataList: List<BaseRealTimeData>, changeTrendGroup: Int) { + if ((eIndex - sIndex + 1) > changeTrendGroup) { + sIndex = eIndex + 1 - changeTrendGroup + startData = historyDataList[sIndex] + exceptionData.clear() +// exceptionData.addAll(historyDataList.subList(sIndex, eIndex + 1)) + exceptionExisted = false + exceptionCreated = false + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionTag.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionTag.kt new file mode 100644 index 0000000..0bb8a4a --- /dev/null +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionTag.kt @@ -0,0 +1,47 @@ +package com.flightfeather.uav.biz.dataanalysis.model + +import com.flightfeather.uav.biz.dataanalysis.BaseExceptionResult +import com.flightfeather.uav.domain.entity.BaseRealTimeData + +/** + * 寮傚父鏁版嵁鏍囩 + * @date 2025/5/13 + * @author feiyu02 + */ +open class ExceptionTag { + // 璧峰鏁版嵁涓嬫爣 + var sIndex = 0 + + // 璧峰鏁版嵁瀵硅薄 + var startData: BaseRealTimeData? = null + + // 鏈熬鏁版嵁涓嬫爣 + var eIndex = -1 + + // 鏈熬鏁版嵁瀵硅薄 + var endData: BaseRealTimeData? = null + + // 寮傚父鏁版嵁娈� + var exceptionData = mutableListOf<BaseRealTimeData>() + + // 鏄惁瀛樺湪寮傚父 + var exceptionExisted = false + + // 寮傚父缁撴灉鏄惁鍒涘缓 + var exceptionCreated = false + + var exceptionResult = mutableListOf<BaseExceptionResult>() + + fun addExceptionData(data: BaseRealTimeData){ + exceptionExisted = true + exceptionData.add(data) + } + + fun refreshWithNextException(data: BaseRealTimeData) { + sIndex = eIndex + startData = data + exceptionData.clear() + exceptionExisted = false + exceptionCreated = false + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/RealTimeAnalysisConfig.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/RealTimeAnalysisConfig.kt index bd28bbb..6ebac98 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/RealTimeAnalysisConfig.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/RealTimeAnalysisConfig.kt @@ -15,25 +15,28 @@ // 闄愬畾璺濈鍐咃紙鍗曚綅锛氱背锛� var distanceLimit = 1000 - // 闄愬畾鏃堕棿鍐咃紙鍗曚綅锛氬垎閽燂級 var timeLimit = 2 // 绐佸彉鏁版嵁涓暟 var mutationNum = 3 - // 绐佸彉鐜� var mutationRate = .2 + // 姹傛粦鍔ㄥ钩鍧囧�肩殑鏁版嵁缁勪釜鏁� + var changeTrendGroup = 12 + // 婊戝姩骞冲潎鍊艰繛缁� + var changeTrendInterval = 12 + var changeTrendRate = .2 + // 婊戝姩骞冲潎鍊煎彉鍖栫巼寮傚父杩炵画娆℃暟 + var changeTrendTimes = 3 + // 婧簮鏈夋晥鏈�澶ф椂闂达紙鍗曚綅锛氬垎閽�) var sourceTraceTimeLimit = 5 - // 婧簮鏈夋晥鏈�澶ц窛绂伙紙鍗曚綅锛氱背锛� var sourceTraceDistanceLimit = 2000 - // 婧簮鏈夋晥鏈�澶ч閫燂紙鍗曚綅锛氱背/绉掞級锛�5鍒嗛挓涓嶈秴杩�2鍏噷鐨勯閫燂紙鏆傚畾锛� var sourceTraceWindSpeedLimit = 6.667 - // 婧簮鎵╂暎鍋忕Щ瑙掑害锛堝崟浣嶏細搴︼級 var sourceTraceDegOffset = 30.0 } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/RealTimeExceptionAnalysisController.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/RealTimeExceptionAnalysisController.kt index 9fb9090..4c47d28 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/RealTimeExceptionAnalysisController.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/RealTimeExceptionAnalysisController.kt @@ -2,6 +2,7 @@ import com.flightfeather.uav.biz.FactorFilter import com.flightfeather.uav.biz.dataanalysis.BaseExceptionAnalysis +import com.flightfeather.uav.biz.sourcetrace.exceptiontype.RealTimeExceptionSlideAverage import com.flightfeather.uav.biz.sourcetrace.exceptiontype.RealTimeExceptionValueMutation import com.flightfeather.uav.biz.sourcetrace.model.RealTimeExceptionResult import com.flightfeather.uav.common.utils.GsonUtils @@ -60,6 +61,9 @@ add( RealTimeExceptionValueMutation(config) { exceptionCallback(it) }.also { it.init() } ) + add( + RealTimeExceptionSlideAverage(config){ exceptionCallback(it)}.also { it.init() } + ) } } diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRealTimeException.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRealTimeException.kt index c464995..bfb6b9a 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRealTimeException.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRealTimeException.kt @@ -2,9 +2,11 @@ import com.flightfeather.uav.biz.FactorFilter import com.flightfeather.uav.biz.dataanalysis.BaseExceptionContinuous +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionTag import com.flightfeather.uav.biz.sourcetrace.RealTimeAnalysisConfig import com.flightfeather.uav.biz.sourcetrace.model.RealTimeExceptionResult import com.flightfeather.uav.domain.entity.BaseRealTimeData +import com.flightfeather.uav.lightshare.eunm.ExceptionStatusType // 寮傚父鏁版嵁鐢熸垚鍥炶皟绫� typealias NewExceptionCallback = (ex: RealTimeExceptionResult) -> Unit @@ -15,10 +17,10 @@ * @date 2025/5/13 * @author feiyu02 */ -abstract class BaseRealTimeException(config: RealTimeAnalysisConfig) : - BaseExceptionContinuous<RealTimeAnalysisConfig, RealTimeExceptionResult>(config) { +abstract class BaseRealTimeException<T : ExceptionTag>(config: RealTimeAnalysisConfig, tagClz: Class<T>) : + BaseExceptionContinuous<T, RealTimeAnalysisConfig, RealTimeExceptionResult>(config, tagClz) { - constructor(config: RealTimeAnalysisConfig, callback: NewExceptionCallback) : this(config){ + constructor(config: RealTimeAnalysisConfig, callback: NewExceptionCallback, tagClz: Class<T>) : this(config, tagClz){ this.callback = callback } @@ -34,19 +36,18 @@ // 璧峰鏁版嵁 it.endData = data if (it.startData == null) { - it.refreshAfterCheckResult(data) + it.refreshWithNextException(data) } // 鍒ゆ柇鐩搁偦鏁版嵁鏄惁杩炵画鎴栬�呮槸鍚︽弧瓒宠嚜瀹氫箟鎴彇鏉′欢 if (!isContinue || needCut(it)) { // 璁板綍寮傚父锛岀粨鏉熷紓甯哥殑瀹炴椂鐘舵�佹挱鎶� recordException(s, it, data) } else { - if (hasException[f] == true) { - it.existException = true - it.exceptionData.add(data) - } // 绉婚櫎浜嗙埗绫诲師鏈夐�昏緫锛屾敼涓哄綋婊¤冻寮傚父鏉′欢鏃讹紝闇�瑕佸疄鏃舵帹閫佹挱鎶ュ紓甯哥殑鐘舵�佸彉鍖栵紝浣嗕笉鎴彇寮傚父 - checkResult(s) + if (hasException[f] == true) { + it.addExceptionData(data) + checkResult(s) + } } } } @@ -63,11 +64,11 @@ return RealTimeExceptionResult(start, end, factor, exceptionData, eType) } - override fun onNewException(tag: Tag, factor: FactorFilter.SelectedFactor) { - super.onNewException(tag, factor) + override fun onNewException(tag: T, factor: FactorFilter.SelectedFactor, exceptionStatus: ExceptionStatusType) { + super.onNewException(tag, factor, exceptionStatus) callback?.let { func -> - val exc = resultList.last() - func.invoke(exc) + val exc = tag.exceptionResult.last() + func.invoke(exc as RealTimeExceptionResult) } } } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionSlideAverage.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionSlideAverage.kt new file mode 100644 index 0000000..8e1aba1 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionSlideAverage.kt @@ -0,0 +1,214 @@ +package com.flightfeather.uav.biz.sourcetrace.exceptiontype + +import com.flightfeather.uav.biz.FactorFilter +import com.flightfeather.uav.biz.dataanalysis.BaseExceptionAnalysis +import com.flightfeather.uav.biz.dataanalysis.exceptiontype.ExceptionSlideAverage.Tag +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionResult +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionSlideAverageTag +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionTag +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionType +import com.flightfeather.uav.biz.sourcetrace.RealTimeAnalysisConfig +import com.flightfeather.uav.biz.sourcetrace.model.RealTimeExceptionResult +import com.flightfeather.uav.domain.entity.BaseRealTimeData +import com.flightfeather.uav.lightshare.eunm.ExceptionStatusType +import com.flightfeather.uav.socket.eunm.FactorType +import kotlin.math.abs + +/** + * 婊戝姩骞冲潎鍊肩獊鍙樺紓甯� + * @date 2025/5/13 + * @author feiyu02 + */ +class RealTimeExceptionSlideAverage : BaseExceptionAnalysis<RealTimeAnalysisConfig, RealTimeExceptionResult> { + + constructor(config: RealTimeAnalysisConfig) : super(config) + + constructor(config: RealTimeAnalysisConfig, callback: NewExceptionCallback) : super(config){ + this.callback = callback + } + + var callback: NewExceptionCallback? = null + + private val historyDataList = mutableListOf<BaseRealTimeData>() + private val tempDataList = mutableListOf<BaseRealTimeData>() + private var lastData: BaseRealTimeData? = null + + protected val tagMap = mutableMapOf<FactorType, ExceptionSlideAverageTag>() + + override fun init() { + super.init() + historyDataList.clear() + tempDataList.clear() + lastData = null + + tagMap.clear() + config.factorFilter.mainList().forEach { f -> + tagMap[f] = ExceptionSlideAverageTag() + } + } + override fun getExceptionType(): ExceptionType { + return ExceptionType.TYPE7 + } + + override fun onNextData(data: BaseRealTimeData) { + historyDataList.add(data) + // 鏁版嵁鍔犲叆涓存椂鏁扮粍 + tempDataList.add(data) + // 鏁版嵁閲忚秴鍑鸿缃暟閲忔椂锛屽幓闄ゅ綋鍓嶆暟鎹粍棣栦釜鏁版嵁 + if (tempDataList.size > config.changeTrendGroup) { + tempDataList.removeAt(0) + } + config.factorFilter.selectedList.forEach { s -> + val f = s.main + tagMap[f]?.let { + it.eIndex++ + it.endData = lastData + if (it.startData == null) { + it.startData = data + } + // 鏁版嵁閲忕瓑浜庤缃暟閲忔椂锛岃绠楀綋鍓嶆暟鎹粍鍧囧�� + if (tempDataList.size == config.changeTrendGroup) { + calAvg(f, tempDataList) + if (checkSlideAvg(f)) { + it.addExceptionData(data) + checkResult(s) + } else { + recordException(s, it, data) + } + } + } + } + lastData = data + } + + override fun onDone() { + checkResult(exceptionStatus = ExceptionStatusType.Ended) + } + + /** + * 寮傚父缁撴潫锛岃褰曞紓甯� + */ + fun recordException(factor: FactorFilter.SelectedFactor, tag: ExceptionSlideAverageTag, data: BaseRealTimeData) { + checkResult(factor, ExceptionStatusType.Ended) + tag.refreshAfterCheckResult(historyDataList, config.changeTrendGroup) + } + + /** + * 褰撳墠鏁版嵁鏈嚭鐜板紓甯告椂锛屾垨鏁版嵁寰幆缁撴潫鏃讹紝鍒ゆ柇鍚庣画姝ラ + */ + private fun checkResult( + factor: FactorFilter.SelectedFactor? = null, + exceptionStatus: ExceptionStatusType = ExceptionStatusType.InProgress + ) { + val tag = tagMap[factor?.main] + if (factor != null && tag != null) { + if (tag.exceptionExisted) { + onNewException(tag, factor, exceptionStatus) + } + } else { + config.factorFilter.selectedList.forEach { f -> + val tag1 = tagMap[f.main] ?: return@forEach + if (tag1.exceptionExisted) { + onNewException(tag1, f, exceptionStatus) + } + } + } + + } + /** + * 鏂板鎴栨洿鏂颁竴鏉″紓甯� + */ + open fun onNewException(tag: ExceptionSlideAverageTag, factor: FactorFilter.SelectedFactor, exceptionStatus: ExceptionStatusType) { + if (tag.startData == null) return + val ex = newResult(tag.startData!!, lastData, factor, tag.exceptionData) + .apply { status = exceptionStatus.value } + // 寮傚父宸插垱寤烘椂锛屾洿鏂板紓甯镐俊鎭� + if (tag.exceptionCreated) { + // 灏嗘渶鏂扮殑寮傚父鐨刧uid璧嬪�肩粰ex + val lastEx = tag.exceptionResult.last() + ex.guid = lastEx.guid + tag.exceptionResult.removeLast() + tag.exceptionResult.add(ex) + } + // 寮傚父鏈垱寤烘椂锛屾柊寤哄紓甯镐俊鎭� + else { + tag.exceptionResult.add(ex) + tag.exceptionCreated = true + } + + callback?.let { func -> + val exc = tag.exceptionResult.last() + func.invoke(exc as RealTimeExceptionResult) + } + } + + + override fun newResult( + start: BaseRealTimeData, + end: BaseRealTimeData?, + factor: FactorFilter.SelectedFactor, + exceptionData: List<BaseRealTimeData>, + ): RealTimeExceptionResult { + val eType = getExceptionType() + return RealTimeExceptionResult(start, end, factor, exceptionData, eType) + } + + /** + * 璁$畻涓�缁勬暟鎹殑鍧囧�� + */ + private fun calAvg(type: FactorType, list: List<BaseRealTimeData>) { + var total = .0 + var valid = true + val count = list.size + if (count == 0) return + list.forEach { + val v = it.getByFactorType(type) + if (v == null) { + valid = false + } else { + total += v + } + } + val avg = total / count + tagMap[type]?.avgListReverse?.add(0, Pair(avg, valid)) + } + + /** + * 璁$畻鏁版嵁缁勪箣闂寸殑鍧囧�煎樊寮傛槸鍚﹁繛缁秴杩囬檺瀹氭瘮鐜� + */ + private fun checkSlideAvg(type: FactorType): Boolean { + val tag = tagMap[type] ?: return false + // 璁$畻婊戝姩鍧囧�兼渶浣庤姹備釜鏁� + val minSize = config.changeTrendTimes + config.changeTrendInterval + if (tag.avgListReverse.size < minSize) { + return false + } else { + // 婊戝姩鍧囧�兼弧瓒虫暟閲忔椂锛岃绠楀潎鍊间箣闂存槸鍚﹁繛缁秴杩囬檺瀹氭瘮鐜� + val rateList = mutableListOf<Pair<Double, Boolean>>() + for (i in tag.avgListReverse.indices) { + if (i >= config.changeTrendTimes) break + val r = calAvgChangeRate(tag.avgListReverse[i], tag.avgListReverse[i + config.changeTrendInterval]) + rateList.add(r) + } + for (y in rateList) { + if (!y.second || y.first < config.changeTrendRate) { + return false + } + } + return true + } + } + + /** + * 璁$畻婊戝姩鍧囧�煎彉鍖栫巼 + * 姹俛1鐩稿浜巃2鐨勫彉鍖栫巼 + */ + private fun calAvgChangeRate(a1: Pair<Double, Boolean>, a2: Pair<Double, Boolean>): Pair<Double, Boolean> { + val valid = a1.second && a2.second + return if (a2.first == .0) { + Pair(1.0, valid) + } else { + Pair(abs(a1.first - a2.first) / a2.first, valid) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionValueMutation.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionValueMutation.kt index f5eb79f..5a97f66 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionValueMutation.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionValueMutation.kt @@ -1,5 +1,6 @@ package com.flightfeather.uav.biz.sourcetrace.exceptiontype +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionTag import com.flightfeather.uav.biz.dataanalysis.model.ExceptionType import com.flightfeather.uav.biz.sourcetrace.RealTimeAnalysisConfig import com.flightfeather.uav.common.utils.MapUtil @@ -14,11 +15,11 @@ * @date 2025/5/13 * @author feiyu02 */ -class RealTimeExceptionValueMutation : BaseRealTimeException { +class RealTimeExceptionValueMutation : BaseRealTimeException<ExceptionTag> { - constructor(config: RealTimeAnalysisConfig) : super(config) + constructor(config: RealTimeAnalysisConfig) : super(config, ExceptionTag::class.java) - constructor(config: RealTimeAnalysisConfig, callback: NewExceptionCallback) : super(config, callback) + constructor(config: RealTimeAnalysisConfig, callback: NewExceptionCallback) : super(config, callback, ExceptionTag::class.java) /** * 鏈紓甯哥殑杩炵画鍙戠敓娆℃暟浼氭牴鎹紓甯哥殑绋嬪害鍙樺寲 @@ -51,18 +52,16 @@ return res } - override fun judgeExceptionCount(tag: Tag): Boolean { - // 棣栦釜鏁版嵁娌℃湁鍓嶄竴涓暟鎹弬鐓э紝涓嶇畻寮傚父鍊硷紝鏈�鍚庝竴涓暟鎹槸鍒ゆ柇缁撴潫鐨勬甯稿�硷紝鍥犳寮傚父鏁版嵁涓暟鐨勮绠椾笅鏍囦负sIndex鍜宔Index - 1 - val sIndex = tag.sIndex - val eIndex = tag.eIndex - 1 + override fun judgeExceptionCount(tag: ExceptionTag): Boolean { + val count = tag.exceptionData.size - val b1 = special && (eIndex - sIndex) >= (config.mutationNum / 2) - val b2 = (eIndex - sIndex) >= config.mutationNum + val b1 = special && count >= (config.mutationNum / 2) + val b2 = count >= config.mutationNum special = false return b1 || b2 } - override fun needCut(tag: Tag): Boolean { + override fun needCut(tag: ExceptionTag): Boolean { // 鎸夌収鏃堕暱鍜岃窛绂婚檺鍒跺皢寮傚父鎴彇 if (tag.exceptionData.isEmpty()) return false diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/RealTimeExceptionResult.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/RealTimeExceptionResult.kt index 8f5d0eb..7a4251f 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/RealTimeExceptionResult.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/RealTimeExceptionResult.kt @@ -11,6 +11,7 @@ import com.flightfeather.uav.lightshare.eunm.ExceptionStatusType import com.flightfeather.uav.socket.eunm.FactorType import java.math.BigDecimal +import java.util.UUID /** * @@ -18,11 +19,6 @@ * @author feiyu02 */ class RealTimeExceptionResult() : BaseExceptionResult() { - - // 寮傚父缂栧彿 - var guid: String? = null - // 寮傚父鐨勭姸鎬� - var status:Int = ExceptionStatusType.InProgress.value var deviceCode: String? = null -- Gitblit v1.9.3