| | |
| | | * ç¡®å®å¼å¸¸ç±»å |
| | | */ |
| | | abstract fun getExceptionType(): ExceptionType |
| | | |
| | | /** |
| | | * çæä¸æ¡å¼å¸¸åæç»æ |
| | | */ |
| | | abstract fun newResult( |
| | | start: BaseRealTimeData, |
| | | end: BaseRealTimeData?, |
| | | factor: FactorFilter.SelectedFactor, |
| | | exceptionData: List<BaseRealTimeData>, |
| | | ): Y |
| | | } |
| | |
| | | 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 { |
| | | // è®°å½å¼å¸¸æ°æ®æ®µæ¶ï¼åå«åèµ·å§å快尾åé¢å¤è®°å½çæ°æ®ä¸ªæ°åç§»é |
| | |
| | | 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 |
| | |
| | | * 夿å¼å¸¸åºç°çè¿ç»ä¸ªæ°æ¯å¦æ»¡è¶³æ¡ä»¶ |
| | | * @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 |
| | | } |
| | | |
| | |
| | | lastData = null |
| | | tagMap.clear() |
| | | config.factorFilter.mainList().forEach { f -> |
| | | tagMap[f] = Tag() |
| | | tagMap[f] = tagClz.newInstance() |
| | | } |
| | | } |
| | | |
| | |
| | | // èµ·å§æ°æ® |
| | | 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) |
| | | // } |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | 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) { |
| | | // å°ææ°çå¼å¸¸çguidèµå¼ç»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 |
| | | } |
| | | |
| | | } |
| | |
| | | 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) |
| | |
| | | } |
| | | // 夿ç¸é»æ°æ®æ¯å¦è¿ç»å¹¶ä¸æ¯å¦æ»¡è¶³å¼å¸¸å¤æ |
| | | 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) |
| | | } |
| | | } |
| | | } |
| | |
| | | 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() |
| | | } |
| | | |
| | | } |
| | |
| | | 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 |
| | | |
| | | /** |
| | |
| | | * @author feiyu02 |
| | | */ |
| | | abstract class ExceptionContinuous(config: DataAnalysisConfig) : |
| | | BaseExceptionContinuous<DataAnalysisConfig, ExceptionResult>(config) { |
| | | BaseExceptionContinuous<ExceptionTag, DataAnalysisConfig, ExceptionResult>(config, ExceptionTag::class.java) { |
| | | |
| | | override fun newResult( |
| | | start: BaseRealTimeData, |
| | |
| | | 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 |
| | |
| | | */ |
| | | @Deprecated("åè¶
æ å¤å®é»è¾è®¾å®çè¶
æ å¼ææ¼æ´ï¼") |
| | | class ExceptionDataExceed(config: DataAnalysisConfig) : |
| | | BaseExceptionContinuousSingle<DataAnalysisConfig, ExceptionResult>(config) { |
| | | BaseExceptionContinuousSingle<ExceptionTag, DataAnalysisConfig, ExceptionResult>(config, ExceptionTag::class.java) { |
| | | |
| | | override fun getExceptionType(): ExceptionType = ExceptionType.TYPE2 |
| | | |
| | |
| | | return res |
| | | } |
| | | |
| | | override fun judgeExceptionCount(tag: Tag): Boolean { |
| | | override fun judgeExceptionCount(tag: ExceptionTag): Boolean { |
| | | return true |
| | | } |
| | | |
| | |
| | | var exceptionData = mutableListOf<BaseRealTimeData>() |
| | | |
| | | // æ¯å¦åå¨å¼å¸¸ |
| | | var existException = false |
| | | var exceptionExisted = false |
| | | |
| | | fun refreshAfterCheckResult(data: BaseRealTimeData) { |
| | | // å¤æå¹¶æ´æ°èµ·å§ç¹ä½ç½® |
| | |
| | | if (tempDataList.size == config.changeTrendGroup) { |
| | | calAvg(f, tempDataList) |
| | | if (checkSlideAvg(f)) { |
| | | it.existException = true |
| | | it.exceptionExisted = true |
| | | it.exceptionData.add(data) |
| | | } else { |
| | | checkResult(s) |
| | |
| | | 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, |
| | |
| | | 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 |
| | |
| | | return res |
| | | } |
| | | |
| | | override fun judgeExceptionCount(tag: Tag): Boolean { |
| | | override fun judgeExceptionCount(tag: ExceptionTag): Boolean { |
| | | // é¦ä¸ªæ°æ®æ²¡æåä¸ä¸ªæ°æ®åç
§ï¼ä¸ç®å¼å¸¸å¼ï¼æåä¸ä¸ªæ°æ®æ¯å¤æç»æçæ£å¸¸å¼ï¼å æ¤å¼å¸¸æ°æ®ä¸ªæ°ç计ç®ä¸æ 为sIndexåeIndex |
| | | val sIndex = tag.sIndex |
| | | val eIndex = tag.eIndex - 1 |
| | |
| | | factorFilter: FactorFilter, |
| | | ) : BaseAnalysisConfig(factorFilter) { |
| | | // è¿ç»çªåæ°æ®ä¸ªæ° |
| | | var mutationNum = 2 |
| | | var mutationNum = 3 |
| | | |
| | | // çªåç |
| | | var mutationRate = .5 |
| | | var mutationRate = .2 |
| | | |
| | | // æ±æ»å¨å¹³åå¼çæ°æ®ç»ä¸ªæ° |
| | | var changeTrendGroup = 12 |
¶Ô±ÈÐÂÎļþ |
| | |
| | | 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 |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | 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 |
| | | } |
| | | } |
| | |
| | | |
| | | // éå®è·ç¦»å
ï¼åä½ï¼ç±³ï¼ |
| | | 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 |
| | | } |
| | |
| | | |
| | | 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 |
| | |
| | | add( |
| | | RealTimeExceptionValueMutation(config) { exceptionCallback(it) }.also { it.init() } |
| | | ) |
| | | add( |
| | | RealTimeExceptionSlideAverage(config){ exceptionCallback(it)}.also { it.init() } |
| | | ) |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | 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 |
| | |
| | | * @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 |
| | | } |
| | | |
| | |
| | | // èµ·å§æ°æ® |
| | | 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) |
| | | } |
| | | // ç§»é¤äºç¶ç±»åæé»è¾ï¼æ¹ä¸ºå½æ»¡è¶³å¼å¸¸æ¡ä»¶æ¶ï¼éè¦å®æ¶æ¨éææ¥å¼å¸¸çç¶æååï¼ä½ä¸æªåå¼å¸¸ |
| | | if (hasException[f] == true) { |
| | | it.addExceptionData(data) |
| | | checkResult(s) |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | 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) |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | 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) { |
| | | // å°ææ°çå¼å¸¸çguidèµå¼ç»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 |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è®¡ç®æ»å¨åå¼ååç |
| | | * æ±a1ç¸å¯¹äºa2çååç |
| | | */ |
| | | 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) |
| | | } |
| | | } |
| | | } |
| | |
| | | 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 |
| | |
| | | * @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) |
| | | |
| | | /** |
| | | * æ¬å¼å¸¸çè¿ç»åçæ¬¡æ°ä¼æ ¹æ®å¼å¸¸çç¨åº¦åå |
| | |
| | | return res |
| | | } |
| | | |
| | | override fun judgeExceptionCount(tag: Tag): Boolean { |
| | | // é¦ä¸ªæ°æ®æ²¡æåä¸ä¸ªæ°æ®åç
§ï¼ä¸ç®å¼å¸¸å¼ï¼æåä¸ä¸ªæ°æ®æ¯å¤æç»æçæ£å¸¸å¼ï¼å æ¤å¼å¸¸æ°æ®ä¸ªæ°ç计ç®ä¸æ 为sIndexåeIndex - 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 |
| | | |
| | |
| | | import com.flightfeather.uav.lightshare.eunm.ExceptionStatusType |
| | | import com.flightfeather.uav.socket.eunm.FactorType |
| | | import java.math.BigDecimal |
| | | import java.util.UUID |
| | | |
| | | /** |
| | | * |
| | |
| | | * @author feiyu02 |
| | | */ |
| | | class RealTimeExceptionResult() : BaseExceptionResult() { |
| | | |
| | | // å¼å¸¸ç¼å· |
| | | var guid: String? = null |
| | | // å¼å¸¸çç¶æ |
| | | var status:Int = ExceptionStatusType.InProgress.value |
| | | |
| | | var deviceCode: String? = null |
| | | |