From 1571cd0f137ced4345fa8785e166a29dc31b6ad1 Mon Sep 17 00:00:00 2001 From: feiyu02 <risaku@163.com> Date: 星期二, 13 五月 2025 17:42:39 +0800 Subject: [PATCH] 1. 新增动态污染溯源的数据异常判断逻辑 2. 新增动态污染溯源websocket连接功能 --- src/main/kotlin/com/flightfeather/uav/socket/handler/BaseHandler.kt | 59 +++ src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/DataAnalysisConfig.kt | 10 src/main/kotlin/com/flightfeather/uav/socket/UnderwaySocketServer.kt | 28 + src/main/kotlin/com/flightfeather/uav/socket/handler/ServerHandler.kt | 3 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionContinuous.kt | 43 ++ src/main/kotlin/com/flightfeather/uav/common/utils/MapUtil.kt | 3 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/RealTimeExceptionAnalysisController.kt | 71 +++ src/main/kotlin/com/flightfeather/uav/common/utils/LocalDateTimeAdapter.java | 30 + src/main/kotlin/com/flightfeather/uav/socket/processor/UnderwayProcessor.kt | 61 ++ src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionSlideAverage.kt | 20 src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionDataExceed.kt | 17 src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionResult.kt | 65 +++ src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuousSingle.kt | 33 - src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionAnalysis.kt | 80 ---- src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt | 3 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/RealTimeExceptionResult.kt | 105 +++++ src/main/kotlin/com/flightfeather/uav/domain/repository/AirDataRep.kt | 3 src/main/kotlin/com/flightfeather/uav/common/utils/GsonUtils.kt | 7 src/main/kotlin/com/flightfeather/uav/UAVApplication.kt | 8 src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionValueMutation.kt | 9 src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionResult.kt | 9 src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt | 126 +++--- src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/ExceptionAnalysisController.kt | 2 /dev/null | 32 - src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/RealTimeAnalysisConfig.kt | 30 + src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionValueMutation.kt | 92 +++++ src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseAnalysisConfig.kt | 14 src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionContinuous.kt | 26 + src/main/kotlin/com/flightfeather/uav/domain/repository/impl/AirDataRepImpl.kt | 12 src/main/kotlin/com/flightfeather/uav/socket/handler/UnderwayWebSocketServerHandler.kt | 55 +++ src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt | 2 31 files changed, 815 insertions(+), 243 deletions(-) diff --git a/src/main/kotlin/com/flightfeather/uav/UAVApplication.kt b/src/main/kotlin/com/flightfeather/uav/UAVApplication.kt index f9023b1..c660050 100644 --- a/src/main/kotlin/com/flightfeather/uav/UAVApplication.kt +++ b/src/main/kotlin/com/flightfeather/uav/UAVApplication.kt @@ -18,10 +18,14 @@ @Autowired lateinit var electricProcessor: ElectricProcessor + @Autowired + lateinit var underwaySocketServer:UnderwaySocketServer + @Bean fun runner() = ApplicationRunner{ - UnderwaySocketServer().startUnderwayServer(9030, underwayProcessor) - UnderwaySocketServer().startElectricServer(9009, electricProcessor) + underwaySocketServer.startWebSocketServer(9031, underwayProcessor) + underwaySocketServer.startUnderwayServer(9030, underwayProcessor) + underwaySocketServer.startElectricServer(9009, electricProcessor) } } diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseAnalysisConfig.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseAnalysisConfig.kt new file mode 100644 index 0000000..c3c1992 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseAnalysisConfig.kt @@ -0,0 +1,14 @@ +package com.flightfeather.uav.biz.dataanalysis + +import com.flightfeather.uav.biz.FactorFilter + +/** + * 鏁版嵁鍒嗘瀽閰嶇疆鍙傛暟鍩虹被 + * @date 2025/5/13 + * @author feiyu02 + */ +abstract class BaseAnalysisConfig( + // 鍥犲瓙绛涢�� + val factorFilter: FactorFilter, +) { +} \ No newline at end of file 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 4023fec..54e05f4 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionAnalysis.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionAnalysis.kt @@ -1,93 +1,17 @@ package com.flightfeather.uav.biz.dataanalysis import com.flightfeather.uav.biz.FactorFilter -import com.flightfeather.uav.biz.dataanalysis.model.DataAnalysisConfig -import com.flightfeather.uav.biz.dataanalysis.model.ExceptionResult import com.flightfeather.uav.biz.dataanalysis.model.ExceptionType -import com.flightfeather.uav.common.utils.DateUtil import com.flightfeather.uav.domain.entity.BaseRealTimeData -import com.flightfeather.uav.domain.entity.avg -import com.flightfeather.uav.socket.eunm.FactorType -import java.time.Duration /** * 鐩戞祴鏁版嵁寮傚父鍒嗘瀽鍩虹被 */ -abstract class BaseExceptionAnalysis(config: DataAnalysisConfig) : - BaseDataAnalysis<BaseRealTimeData, DataAnalysisConfig, ExceptionResult>(config) { +abstract class BaseExceptionAnalysis<V : BaseAnalysisConfig, Y : BaseExceptionResult>(config: V) : + BaseDataAnalysis<BaseRealTimeData, V, Y>(config) { /** * 纭畾寮傚父绫诲瀷 */ abstract fun getExceptionType(): ExceptionType - - /** - * 鍒ゆ柇鐩搁偦鏁版嵁鏄惁杩炵画 - */ - open fun isContinuous(d1: BaseRealTimeData?, d2: BaseRealTimeData?): Boolean { - if (d1 == null || d2 == null) return true - - val t1 = d1.dataTime - val t2 = d2.dataTime - return Duration.between(t1?.toInstant(), t2?.toInstant()).toMillis() <= (20 * 1000) - } - - /** - * 鐢熸垚涓�鏉″紓甯稿垎鏋愮粨鏋� - */ - open fun newResult( - start: BaseRealTimeData, end: BaseRealTimeData?, factor: FactorFilter.SelectedFactor, - exceptionData: List<BaseRealTimeData>, - ): ExceptionResult { - val eType = getExceptionType() - return ExceptionResult().apply { - missionCode = config.mission.missionCode - deviceCode = start.deviceCode - exception = eType.des - exceptionType = eType.value - factorId = factor.main.value - factorName = factor.main.des - subFactorId = factor.subs.map { it.value } - subFactorName = factor.subs.map { it.des } - selectedFactor = factor - startDate = start.dataTime - endDate = end?.dataTime - startTime = DateUtil.instance.dateToString(start.dataTime, DateUtil.DateStyle.HH_MM_SS) - endTime = DateUtil.instance.dateToString(end?.dataTime, DateUtil.DateStyle.HH_MM_SS) ?: startTime - startData = start.getByFactorType(factor.main) - endData = end?.getByFactorType(factor.main) ?: startData - - val avgData = exceptionData.avg() - // 姹傚彇姹℃煋鏁版嵁鐨勪腑蹇冨潗鏍� - longitude = avgData.longitude - latitude = avgData.latitude - // 姹傚彇涓绘薄鏌撳洜瀛愮殑鍧囧�煎拰鑼冨洿 - val s = dataSummary(exceptionData, factor.main) - avg = s.first - min = s.second - max = s.third - - exceptionData.forEach { dataList.add(it) } - } - } - - private fun dataSummary(exceptionData: List<BaseRealTimeData?>, factorType: FactorType): Triple<Float, Float, Float> { - var min = -1f - var max = -1f - var total = 0f - var count = 0 - exceptionData.forEach { - val value = it?.getByFactorType(factorType) ?: return@forEach - if (min == -1f || min > value) { - min = value - } - if (max == -1f || max < value) { - max = value - } - total += value - count++ - } - val avg = if (count == 0) 0f else total / count - return Triple(avg, min, max) - } } \ 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 63cd9af..52f9cac 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt @@ -1,14 +1,15 @@ package com.flightfeather.uav.biz.dataanalysis import com.flightfeather.uav.biz.FactorFilter -import com.flightfeather.uav.biz.dataanalysis.model.DataAnalysisConfig import com.flightfeather.uav.domain.entity.BaseRealTimeData import com.flightfeather.uav.socket.eunm.FactorType +import java.time.Duration /** * 杩炵画绫诲瀷鐨勫紓甯稿垎鏋愬熀绫�,閫傜敤浜庡綋鍓嶆暟鎹笌鐩搁偦鏁版嵁涔嬮棿鏈夊叧鑱斿叧绯荤殑鎯呭喌 */ -abstract class BaseExceptionContinuous(config: DataAnalysisConfig) : BaseExceptionAnalysis(config) { +abstract class BaseExceptionContinuous<V : BaseAnalysisConfig, Y : BaseExceptionResult>(config: V) : + BaseExceptionAnalysis<V, Y>(config) { companion object { // 璁板綍寮傚父鏁版嵁娈垫椂锛屽垎鍒悜璧峰鍓嶅拰鏈熬鍚庨澶栬褰曠殑鏁版嵁涓暟鍋忕Щ閲� @@ -20,7 +21,7 @@ var sIndex = 0 // 璧峰鏁版嵁瀵硅薄 - var startData :BaseRealTimeData? = null + var startData: BaseRealTimeData? = null // 鏈熬鏁版嵁涓嬫爣 var eIndex = -1 @@ -38,30 +39,28 @@ sIndex = eIndex startData = data exceptionData.clear() - exceptionData.add(data) +// exceptionData.add(data) } } protected val tagMap = mutableMapOf<FactorType, Tag>() -// // 璧峰鏁版嵁涓嬫爣 -// protected var sIndex = mutableListOf<Int>() -// -// // 璧峰鏁版嵁瀵硅薄 -// protected var startData = mutableListOf<BaseRealTimeData?>() -// -// // 鏈熬鏁版嵁涓嬫爣 -// protected var eIndex = mutableListOf<Int>() -// -// // 寮傚父鏁版嵁娈� -// protected var exceptionData = mutableListOf<MutableList<BaseRealTimeData>>() - -// protected var existException = mutableListOf<Boolean>() - // 璧峰鏁版嵁涓庢湯灏炬暟鎹棿闅� open var durationCount = 1 + // 鏈熬鏁版嵁瀵硅薄 protected var lastData: BaseRealTimeData? = null + + /** + * 鍒ゆ柇鐩搁偦鏁版嵁鏄惁杩炵画 + */ + open fun isContinuous(d1: BaseRealTimeData?, d2: BaseRealTimeData?): Boolean { + if (d1 == null || d2 == null) return true + + val t1 = d1.dataTime + val t2 = d2.dataTime + return Duration.between(t1?.toInstant(), t2?.toInstant()).toMillis() <= (20 * 1000) + } /** * 鍒ゆ柇鏄惁婊¤冻寮傚父鏉′欢 @@ -69,24 +68,25 @@ abstract fun judgeException(p: BaseRealTimeData?, n: BaseRealTimeData): MutableMap<FactorType, Boolean> /** - * 鍒ゆ柇寮傚父鍑虹幇鐨勮繛缁椂闀挎槸鍚︽弧瓒虫潯浠� - * @param sIndex - * @param eIndex + * 鍒ゆ柇寮傚父鍑虹幇鐨勮繛缁釜鏁版槸鍚︽弧瓒虫潯浠� + * @param tag 寮傚父鏁版嵁瀵硅薄 */ - abstract fun judgeDuration(sIndex: Int, eIndex: Int): Boolean + abstract fun judgeExceptionCount(tag: Tag): Boolean + + /** + * 寮傚父鏁版嵁鐨勬埅鍙栧垽鏂� + * 鏄惁闇�瑕侀檺鍒朵竴缁勫紓甯告暟鎹殑闀垮害 + * @return 榛樿涓嶉渶瑕佹埅鍙� + */ + open fun needCut(tag: Tag): Boolean { + return false + } override fun init() { super.init() lastData = null -// repeat(config.factorCount) { -// startData.add(null) -// sIndex.add(0) -// eIndex.add(-1) -// existException.add(false) -// exceptionData.add(mutableListOf()) -// } tagMap.clear() - config.factorFilter.mainList().forEach {f-> + config.factorFilter.mainList().forEach { f -> tagMap[f] = Tag() } } @@ -94,17 +94,17 @@ override fun onNextData(data: BaseRealTimeData) { val isContinue = isContinuous(lastData, data) val hasException = judgeException(lastData, data) - config.factorFilter.selectedList.forEach {s-> + config.factorFilter.selectedList.forEach { s -> val f = s.main tagMap[f]?.let { it.eIndex++ // 璧峰鏁版嵁 - it.endData = lastData - if (it.endData == null) { + it.endData = data + if (it.startData == null) { it.refreshAfterCheckResult(data) } // 鍒ゆ柇鐩搁偦鏁版嵁鏄惁杩炵画骞朵笖鏄惁婊¤冻寮傚父鍒ゆ柇 - if (!isContinue) { + if (!isContinue || needCut(it)) { checkResult(s) // 鏁版嵁涓嶈繛缁椂锛岃褰曞紓甯告儏鍐� if (it.eIndex - it.sIndex >= durationCount) { @@ -131,43 +131,51 @@ checkResult() } -// fun refreshAfterCheckResult(i:Int, data: BaseRealTimeData) { -// sIndex[i] = eIndex[i] -// startData[i] = data -// exceptionData[i].clear() -// exceptionData[i].add(data) -// } - /** * 妫�鏌ヨ繛缁紓甯哥粨鏉熸椂锛屾槸鍚︾鍚堝紓甯稿瓨鍌ㄦ潯浠� */ open fun checkResult(factor: FactorFilter.SelectedFactor? = null) { val tag = tagMap[factor?.main] if (factor != null && tag != null) { - if (tag.existException && judgeDuration(tag.sIndex, tag.eIndex - 1)) { - tag.startData?.let { - resultList.add(newResult(it, lastData, factor, tag.exceptionData)) - } - tag.existException = false + if (tag.existException && judgeExceptionCount(tag)) { + onNewException(tag, factor) +// tag.startData?.let { +// resultList.add(newResult(it, lastData, factor, tag.exceptionData)) +// } +// tag.existException = false } } else { config.factorFilter.selectedList.forEach { f -> val tag1 = tagMap[f.main] ?: return@forEach - if (tag1.existException && judgeDuration(tag1.sIndex, tag1.eIndex - 1)) { - tag1.startData?.let { - resultList.add(newResult(it, lastData, f, tag1.exceptionData)) - } - tag1.existException = false + if (tag1.existException && judgeExceptionCount(tag1)) { + onNewException(tag1, f) +// tag1.startData?.let { +// resultList.add(newResult(it, lastData, f, tag1.exceptionData)) +// } +// tag1.existException = false } } -// repeat(config.factorCount) { i -> -// if (existException[i] && judgeDuration(sIndex[i], eIndex[i])) { -// startData[i]?.let { -// resultList.add(newResult(it, lastData, i, exceptionData[i])) -// } -// existException[i] = false -// } -// } } } + + /** + * 鏂板涓�鏉″紓甯� + */ + open fun onNewException(tag:Tag, factor: FactorFilter.SelectedFactor) { + tag.startData?.let { + resultList.add(newResult(it, lastData, factor, tag.exceptionData)) + } + tag.existException = false + } + + /** + * 鐢熸垚涓�鏉″紓甯稿垎鏋愮粨鏋� + */ + 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 9a10bdc..3912148 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuousSingle.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuousSingle.kt @@ -1,17 +1,17 @@ package com.flightfeather.uav.biz.dataanalysis -import com.flightfeather.uav.biz.dataanalysis.model.DataAnalysisConfig import com.flightfeather.uav.domain.entity.BaseRealTimeData /** * 杩炵画绫诲瀷鐨勫紓甯稿垎鏋愬熀绫�,鍖哄埆浜庣埗绫荤殑鍦版柟鍦ㄤ簬姝ょ寮傚父鍙拰鍗曚釜鏁版嵁鏈韩鏈夊叧,涓庣浉閭绘暟鎹棤鍏� */ -abstract class BaseExceptionContinuousSingle(config: DataAnalysisConfig) : BaseExceptionContinuous(config) { +abstract class BaseExceptionContinuousSingle<V : BaseAnalysisConfig, Y : BaseExceptionResult>(config: V) : + BaseExceptionContinuous<V, Y>(config) { override fun onNextData(data: BaseRealTimeData) { val isContinue = isContinuous(lastData, data) val hasException = judgeException(lastData, data) - config.factorFilter.selectedList.forEach {s-> + config.factorFilter.selectedList.forEach { s -> val f = s.main tagMap[f]?.let { it.eIndex++ @@ -19,12 +19,12 @@ it.startData = data } // 鍒ゆ柇鐩搁偦鏁版嵁鏄惁杩炵画骞朵笖鏄惁婊¤冻寮傚父鍒ゆ柇 - if (!isContinue) { + if (!isContinue || needCut(it)) { checkResult(s) it.refreshAfterCheckResult(data) } else { if (hasException[f] == true) { - // 淇敼浜嗚捣濮嬫暟鎹殑浣嶇疆,鍙樻洿涓哄嚭鐜板紓甯哥殑璇ュ��,鑰屼笉鏄師鏉ョ殑鍑虹幇寮傚父鐨勬暟鎹殑鍓嶄竴涓�� + // 淇敼浜嗚捣濮嬫暟鎹殑浣嶇疆,鍙樻洿涓哄嚭鐜板紓甯哥殑璇ュ��,鑰屼笉鏄師鏉ョ殑鍑虹幇寮傚父鏁版嵁鐨勫墠涓�涓�� if (!it.existException) { it.sIndex = it.eIndex it.startData = data @@ -38,29 +38,6 @@ } } } -// repeat(config.factorCount) { i -> -// eIndex[i]++ -// if (lastData == null) { -// startData[i] = data -// } -// // 鍒ゆ柇鐩搁偦鏁版嵁鏄惁杩炵画骞朵笖鏄惁婊¤冻寮傚父鍒ゆ柇 -// if (!isContinue) { -// checkResult() -// sIndex[i] = eIndex[i] -// startData[i] = data -// } else { -// if (hasException[i]) { -// // 淇敼浜嗚捣濮嬫暟鎹殑浣嶇疆,鍙樻洿涓哄嚭鐜板紓甯哥殑璇ュ��,鑰屼笉鏄師鏉ョ殑鍑虹幇寮傚父鐨勬暟鎹殑鍓嶄竴涓�� -// if (!existException[i]) { -// sIndex[i] = eIndex[i] -// startData[i] = data -// } -// existException[i] = true -// } else { -// checkResult() -// } -// } -// } lastData = data } } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionResult.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionResult.kt new file mode 100644 index 0000000..3500ba0 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionResult.kt @@ -0,0 +1,9 @@ +package com.flightfeather.uav.biz.dataanalysis + +/** + * 寮傚父缁撴灉鍩虹被 + * @date 2025/5/13 + * @author feiyu02 + */ +abstract class BaseExceptionResult { +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/ExceptionAnalysisController.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/ExceptionAnalysisController.kt index d2f3c57..556353a 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/ExceptionAnalysisController.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/ExceptionAnalysisController.kt @@ -25,7 +25,7 @@ var running = false - private val taskList = mutableListOf<BaseExceptionAnalysis>() + private val taskList = mutableListOf<BaseExceptionAnalysis<DataAnalysisConfig, ExceptionResult>>() private fun initTask(config: DataAnalysisConfig) { taskList.clear() diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/RealTimeExceptionAnalysisController.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/RealTimeExceptionAnalysisController.kt deleted file mode 100644 index 91bd310..0000000 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/RealTimeExceptionAnalysisController.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.flightfeather.uav.biz.dataanalysis - -import com.flightfeather.uav.biz.dataanalysis.exceptiontype.ExceptionSlideAverage -import com.flightfeather.uav.biz.dataanalysis.exceptiontype.ExceptionValueMutation -import com.flightfeather.uav.biz.dataanalysis.model.DataAnalysisConfig -import com.flightfeather.uav.common.location.LocationRoadNearby -import com.flightfeather.uav.domain.repository.RealTimeDataRep -import com.flightfeather.uav.domain.repository.SegmentInfoRep - -/** - * - * @date 2025/5/8 - * @author feiyu02 - */ -class RealTimeExceptionAnalysisController ( - private val realTimeDataRep: RealTimeDataRep, - private val locationRoadNearby: LocationRoadNearby, - private val segmentInfoRep: SegmentInfoRep, -){ - - private val taskList = mutableListOf<BaseExceptionAnalysis>() - - private fun initTask(config: DataAnalysisConfig) { - taskList.clear() - taskList.apply { - add(ExceptionValueMutation(config)) - add(ExceptionSlideAverage(config)) - } - } - - // 璁$畻鍘嗗彶浠诲姟 -} \ 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 new file mode 100644 index 0000000..3af5a17 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionContinuous.kt @@ -0,0 +1,26 @@ +package com.flightfeather.uav.biz.dataanalysis.exceptiontype + +import com.flightfeather.uav.biz.FactorFilter +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.domain.entity.BaseRealTimeData + +/** + * 杩炵画绫诲瀷鐨勫紓甯稿垎鏋愬熀绫�,閫傜敤浜庡綋鍓嶆暟鎹笌鐩搁偦鏁版嵁涔嬮棿鏈夊叧鑱斿叧绯荤殑鎯呭喌 + * @date 2025/5/13 + * @author feiyu02 + */ +abstract class ExceptionContinuous(config: DataAnalysisConfig) : + BaseExceptionContinuous<DataAnalysisConfig, ExceptionResult>(config) { + + override fun newResult( + start: BaseRealTimeData, + end: BaseRealTimeData?, + factor: FactorFilter.SelectedFactor, + exceptionData: List<BaseRealTimeData>, + ): ExceptionResult { + val eType = getExceptionType() + return ExceptionResult(start, end, factor, exceptionData, config.mission.missionCode, eType) + } +} \ No newline at end of file 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 3bf7937..f57c775 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 @@ -1,7 +1,9 @@ package com.flightfeather.uav.biz.dataanalysis.exceptiontype +import com.flightfeather.uav.biz.FactorFilter 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.ExceptionType import com.flightfeather.uav.domain.entity.BaseRealTimeData import com.flightfeather.uav.socket.eunm.FactorType @@ -10,7 +12,8 @@ * 鏁版嵁瓒呮爣寮傚父鍒嗘瀽 */ @Deprecated("鍘熻秴鏍囧垽瀹氶�昏緫璁惧畾鐨勮秴鏍囧�兼湁婕忔礊锛�") -class ExceptionDataExceed(config: DataAnalysisConfig) : BaseExceptionContinuousSingle(config) { +class ExceptionDataExceed(config: DataAnalysisConfig) : + BaseExceptionContinuousSingle<DataAnalysisConfig, ExceptionResult>(config) { override fun getExceptionType(): ExceptionType = ExceptionType.TYPE2 @@ -29,7 +32,17 @@ return res } - override fun judgeDuration(sIndex: Int, eIndex: Int): Boolean { + override fun judgeExceptionCount(tag: Tag): Boolean { return true } + + override fun newResult( + start: BaseRealTimeData, + end: BaseRealTimeData?, + factor: FactorFilter.SelectedFactor, + exceptionData: List<BaseRealTimeData>, + ): ExceptionResult { + val eType = getExceptionType() + return ExceptionResult(start, end, factor, exceptionData, config.mission.missionCode, eType) + } } \ No newline at end of file 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 391e20d..6ac4ab8 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 @@ -3,6 +3,7 @@ import com.flightfeather.uav.biz.FactorFilter import com.flightfeather.uav.biz.dataanalysis.BaseExceptionAnalysis import com.flightfeather.uav.biz.dataanalysis.model.DataAnalysisConfig +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionResult import com.flightfeather.uav.biz.dataanalysis.model.ExceptionType import com.flightfeather.uav.domain.entity.BaseRealTimeData import com.flightfeather.uav.socket.eunm.FactorType @@ -11,7 +12,8 @@ /** * 婊戝姩骞冲潎鍊肩獊鍙樺紓甯� */ -class ExceptionSlideAverage(config: DataAnalysisConfig) : BaseExceptionAnalysis(config) { +class ExceptionSlideAverage(config: DataAnalysisConfig) : + BaseExceptionAnalysis<DataAnalysisConfig, ExceptionResult>(config) { private val historyDataList = mutableListOf<BaseRealTimeData>() private val tempDataList = mutableListOf<BaseRealTimeData>() @@ -27,7 +29,7 @@ var sIndex = 0 // 璧峰鏁版嵁瀵硅薄 - var startData :BaseRealTimeData? = null + var startData: BaseRealTimeData? = null // 鏈熬鏁版嵁涓嬫爣 var eIndex = -1 @@ -66,7 +68,7 @@ lastData = null tagMap.clear() - config.factorFilter.mainList().forEach {f-> + config.factorFilter.mainList().forEach { f -> tagMap[f] = Tag() } // avgListReverse.clear() @@ -86,7 +88,7 @@ if (tempDataList.size > config.changeTrendGroup) { tempDataList.removeAt(0) } - config.factorFilter.selectedList.forEach {s-> + config.factorFilter.selectedList.forEach { s -> val f = s.main tagMap[f]?.let { it.eIndex++ @@ -198,4 +200,14 @@ } } + + fun newResult( + start: BaseRealTimeData, + end: BaseRealTimeData?, + factor: FactorFilter.SelectedFactor, + exceptionData: List<BaseRealTimeData>, + ): ExceptionResult { + val eType = getExceptionType() + return ExceptionResult(start, end, factor, exceptionData, config.mission.missionCode, eType) + } } \ No newline at end of file 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 e7994b7..582223b 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,5 @@ package com.flightfeather.uav.biz.dataanalysis.exceptiontype -import com.flightfeather.uav.biz.dataanalysis.BaseExceptionContinuous import com.flightfeather.uav.biz.dataanalysis.model.DataAnalysisConfig import com.flightfeather.uav.biz.dataanalysis.model.ExceptionType import com.flightfeather.uav.domain.entity.BaseRealTimeData @@ -10,7 +9,7 @@ /** * 閲忕骇绐佸彉寮傚父鍒嗘瀽 */ -class ExceptionValueMutation(config: DataAnalysisConfig) : BaseExceptionContinuous(config) { +class ExceptionValueMutation(config: DataAnalysisConfig) : ExceptionContinuous(config) { /** * 鏈紓甯哥殑杩炵画鍙戠敓娆℃暟浼氭牴鎹紓甯哥殑绋嬪害鍙樺寲 @@ -40,7 +39,11 @@ return res } - override fun judgeDuration(sIndex: Int, eIndex: Int): Boolean { + override fun judgeExceptionCount(tag: Tag): Boolean { + // 棣栦釜鏁版嵁娌℃湁鍓嶄竴涓暟鎹弬鐓э紝涓嶇畻寮傚父鍊硷紝鏈�鍚庝竴涓暟鎹槸鍒ゆ柇缁撴潫鐨勬甯稿�硷紝鍥犳寮傚父鏁版嵁涓暟鐨勮绠椾笅鏍囦负sIndex鍜宔Index + val sIndex = tag.sIndex + val eIndex = tag.eIndex - 1 + val b1 = special && (eIndex - sIndex) >= (config.mutationNum / 2) val b2 = (eIndex - sIndex) >= config.mutationNum special = false 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 033514f..165586f 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 @@ -1,29 +1,33 @@ package com.flightfeather.uav.biz.dataanalysis.model import com.flightfeather.uav.biz.FactorFilter +import com.flightfeather.uav.biz.dataanalysis.BaseAnalysisConfig import com.flightfeather.uav.domain.entity.Mission /** * 鏁版嵁鍒嗘瀽閰嶇疆鍙傛暟 */ -data class DataAnalysisConfig( +class DataAnalysisConfig( // 璧拌埅浠诲姟淇℃伅 val mission: Mission, // 鏁版嵁寮傚父閰嶇疆 val exceptionSetting: ExceptionSetting, // 鍥犲瓙绛涢�� - val factorFilter: FactorFilter, -){ + factorFilter: FactorFilter, +) : BaseAnalysisConfig(factorFilter) { // 杩炵画绐佸彉鏁版嵁涓暟 var mutationNum = 2 + // 绐佸彉鐜� var mutationRate = .5 // 姹傛粦鍔ㄥ钩鍧囧�肩殑鏁版嵁缁勪釜鏁� var changeTrendGroup = 12 + // 婊戝姩骞冲潎鍊艰繛缁� var changeTrendInterval = 12 var changeTrendRate = .2 + // 婊戝姩骞冲潎鍊煎彉鍖栫巼寮傚父杩炵画娆℃暟 var changeTrendTimes = 3 diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionResult.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionResult.kt index 9d80c20..2929675 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionResult.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionResult.kt @@ -1,16 +1,20 @@ package com.flightfeather.uav.biz.dataanalysis.model import com.flightfeather.uav.biz.FactorFilter +import com.flightfeather.uav.biz.dataanalysis.BaseExceptionResult +import com.flightfeather.uav.common.utils.DateUtil import com.flightfeather.uav.domain.entity.BaseRealTimeData import com.flightfeather.uav.domain.entity.SceneInfo +import com.flightfeather.uav.domain.entity.avg import com.flightfeather.uav.lightshare.bean.DataVo +import com.flightfeather.uav.socket.eunm.FactorType import java.math.BigDecimal import java.util.* /** * 寮傚父缁撴灉 */ -open class ExceptionResult { +open class ExceptionResult(): BaseExceptionResult() { var missionCode: String? = null var deviceCode: String? = null var exception: String? = null @@ -40,7 +44,64 @@ // 鐩稿叧浼佷笟鍚嶇О锛堝悕绉颁箣闂�;鍒嗛殧锛� var relatedSceneName: List<String>? = null var relatedSceneList: List<SceneInfo?>? = null - // 寮傚父鏁版嵁锛屽ご灏惧彲鑳藉寘鍚竴瀹氶噺鐨勫亸绉� + // 寮傚父鏁版嵁 var dataList: MutableList<BaseRealTimeData> = mutableListOf() var dataVoList: List<DataVo>? = null + + constructor( + start: BaseRealTimeData, + end: BaseRealTimeData?, + factor: FactorFilter.SelectedFactor, + exceptionData: List<BaseRealTimeData>, + missionCode: String?, + eType: ExceptionType, + ) : this() { + this.missionCode = missionCode + deviceCode = start.deviceCode + exception = eType.des + exceptionType = eType.value + factorId = factor.main.value + factorName = factor.main.des + subFactorId = factor.subs.map { it.value } + subFactorName = factor.subs.map { it.des } + selectedFactor = factor + startDate = start.dataTime + endDate = end?.dataTime + startTime = DateUtil.instance.dateToString(start.dataTime, DateUtil.DateStyle.HH_MM_SS) + endTime = DateUtil.instance.dateToString(end?.dataTime, DateUtil.DateStyle.HH_MM_SS) ?: startTime + startData = start.getByFactorType(factor.main) + endData = end?.getByFactorType(factor.main) ?: startData + + val avgData = exceptionData.avg() + // 姹傚彇姹℃煋鏁版嵁鐨勪腑蹇冨潗鏍� + longitude = avgData.longitude + latitude = avgData.latitude + // 姹傚彇涓绘薄鏌撳洜瀛愮殑鍧囧�煎拰鑼冨洿 + val s = dataSummary(exceptionData, factor.main) + avg = s.first + min = s.second + max = s.third + + exceptionData.forEach { dataList.add(it) } + } + + private fun dataSummary(exceptionData: List<BaseRealTimeData?>, factorType: FactorType): Triple<Float, Float, Float> { + var min = -1f + var max = -1f + var total = 0f + var count = 0 + exceptionData.forEach { + val value = it?.getByFactorType(factorType) ?: return@forEach + if (min == -1f || min > value) { + min = value + } + if (max == -1f || max < value) { + max = value + } + total += value + count++ + } + val avg = if (count == 0) 0f else total / count + return Triple(avg, min, max) + } } \ 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 new file mode 100644 index 0000000..6f8a4af --- /dev/null +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/RealTimeAnalysisConfig.kt @@ -0,0 +1,30 @@ +package com.flightfeather.uav.biz.sourcetrace + +import com.flightfeather.uav.biz.FactorFilter +import com.flightfeather.uav.biz.dataanalysis.BaseAnalysisConfig + +/** + * 瀹炴椂璧拌埅姹℃煋婧簮璁$畻鍙傛暟 + * @date 2025/5/13 + * @author feiyu02 + */ +class RealTimeAnalysisConfig( + // 鍥犲瓙绛涢�� + factorFilter: FactorFilter, +) : BaseAnalysisConfig(factorFilter) { + + // 闄愬畾璺濈鍐咃紙鍗曚綅锛氱背锛� + var distanceLimit = 1000 + + // 闄愬畾鏃堕棿鍐咃紙鍗曚綅锛氬垎閽燂級 + var timeLimit = 2 + + // 绐佸彉鏁版嵁涓暟 + var mutationNum = 3 + + // 绐佸彉鐜� + var mutationRate = .2 + + // 婧簮鏈夋晥鏈�澶ч閫燂紝5鍒嗛挓涓嶈秴杩�2鍏噷鐨勯閫燂紙鏆傚畾锛� + var sourceTraceWindSpeedLimit = 6.7 +} \ 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 new file mode 100644 index 0000000..4bd356a --- /dev/null +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/RealTimeExceptionAnalysisController.kt @@ -0,0 +1,71 @@ +package com.flightfeather.uav.biz.sourcetrace + +import com.flightfeather.uav.biz.FactorFilter +import com.flightfeather.uav.biz.dataanalysis.BaseExceptionAnalysis +import com.flightfeather.uav.biz.sourcetrace.exceptiontype.RealTimeExceptionValueMutation +import com.flightfeather.uav.biz.sourcetrace.model.RealTimeExceptionResult +import com.flightfeather.uav.common.api2word.utils.JsonUtils +import com.flightfeather.uav.common.location.LocationRoadNearby +import com.flightfeather.uav.common.utils.GsonUtils +import com.flightfeather.uav.domain.entity.BaseRealTimeData +import com.flightfeather.uav.domain.entity.avg +import com.flightfeather.uav.domain.repository.RealTimeDataRep +import com.flightfeather.uav.domain.repository.SegmentInfoRep +import com.flightfeather.uav.socket.handler.UnderwayWebSocketServerHandler +import com.google.gson.Gson + +/** + * 瀹炴椂璧拌埅姹℃煋婧簮 + * @date 2025/5/8 + * @author feiyu02 + */ +class RealTimeExceptionAnalysisController ( + private val realTimeDataRep: RealTimeDataRep, + private val locationRoadNearby: LocationRoadNearby, + private val segmentInfoRep: SegmentInfoRep, + private val underwayWebSocketServerHandler: UnderwayWebSocketServerHandler, + factorFilter: FactorFilter +){ + private var config:RealTimeAnalysisConfig = RealTimeAnalysisConfig(factorFilter) + + private val taskList = mutableListOf<BaseExceptionAnalysis<RealTimeAnalysisConfig, RealTimeExceptionResult>>() + + private fun initTask(config: RealTimeAnalysisConfig) { + taskList.clear() + taskList.apply { + add(RealTimeExceptionValueMutation(config){ exceptionCallback(it)}) + } + } + + init { + initTask(config) + } + + // 璁$畻鍘嗗彶浠诲姟 + fun addOneData(data: BaseRealTimeData) { + taskList + + } + + private fun exceptionCallback(ex: RealTimeExceptionResult) { + if (sourceTrace(ex, config)) { + underwayWebSocketServerHandler.broadcast(GsonUtils.gson.toJson(ex)) + } + } + + private fun sourceTrace(ex: RealTimeExceptionResult, config: RealTimeAnalysisConfig):Boolean { + val avgData = ex.dataList.avg() + if (avgData.windSpeed!! > config.sourceTraceWindSpeedLimit) { + return false + } + + // 鍙栦腑闂寸偣浣滀负鍙嶅悜婧簮鐨勮捣鐐� + val midData = ex.dataList[ex.dataList.size / 2] + +// avgData.longitude +// avgData.latitude +// avgData.windDirection + return false + } + +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionContinuous.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionContinuous.kt new file mode 100644 index 0000000..ce7c9b4 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionContinuous.kt @@ -0,0 +1,43 @@ +package com.flightfeather.uav.biz.sourcetrace.exceptiontype + +import com.flightfeather.uav.biz.FactorFilter +import com.flightfeather.uav.biz.dataanalysis.BaseExceptionContinuous +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionResult +import com.flightfeather.uav.biz.sourcetrace.RealTimeAnalysisConfig +import com.flightfeather.uav.biz.sourcetrace.model.RealTimeExceptionResult +import com.flightfeather.uav.domain.entity.BaseRealTimeData + +// 寮傚父鏁版嵁鐢熸垚鍥炶皟绫� +typealias NewExceptionCallback = (ex: RealTimeExceptionResult) -> Unit +/** + * + * @date 2025/5/13 + * @author feiyu02 + */ +abstract class RealTimeExceptionContinuous(config: RealTimeAnalysisConfig) : + BaseExceptionContinuous<RealTimeAnalysisConfig, RealTimeExceptionResult>(config) { + + constructor(config: RealTimeAnalysisConfig, callback: NewExceptionCallback) : this(config){ + this.callback = callback + } + + var callback: NewExceptionCallback? = null + + override fun newResult( + start: BaseRealTimeData, + end: BaseRealTimeData?, + factor: FactorFilter.SelectedFactor, + exceptionData: List<BaseRealTimeData>, + ): RealTimeExceptionResult { + val eType = getExceptionType() + return RealTimeExceptionResult(start, end, factor, exceptionData, eType) + } + + override fun onNewException(tag: Tag, factor: FactorFilter.SelectedFactor) { + super.onNewException(tag, factor) + callback?.let { func -> + val exc = resultList.last() + func.invoke(exc) + } + } +} \ 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 new file mode 100644 index 0000000..b87f479 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionValueMutation.kt @@ -0,0 +1,92 @@ +package com.flightfeather.uav.biz.sourcetrace.exceptiontype + +import com.flightfeather.uav.biz.FactorFilter +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionType +import com.flightfeather.uav.biz.sourcetrace.RealTimeAnalysisConfig +import com.flightfeather.uav.common.utils.MapUtil +import com.flightfeather.uav.domain.entity.BaseRealTimeData +import com.flightfeather.uav.socket.eunm.FactorType +import java.time.Duration +import java.time.LocalDateTime +import java.time.ZoneId + +/** + * 閲忕骇绐佸彉寮傚父婧簮 + * @date 2025/5/13 + * @author feiyu02 + */ +class RealTimeExceptionValueMutation : RealTimeExceptionContinuous { + + constructor(config: RealTimeAnalysisConfig) : super(config) + + constructor(config: RealTimeAnalysisConfig, callback: NewExceptionCallback) : super(config, callback) + + /** + * 鏈紓甯哥殑杩炵画鍙戠敓娆℃暟浼氭牴鎹紓甯哥殑绋嬪害鍙樺寲 + * 褰撶獊鍙樼殑閲忕骇瓒呰繃璁惧畾鍊�1鍊嶆椂,杩炵画鍙戠敓娆℃暟瑕佹眰鍑忓皯1鍊� + */ + private var special = false + + override fun getExceptionType(): ExceptionType { + return ExceptionType.TYPE4 + } + + override fun judgeException(p: BaseRealTimeData?, n: BaseRealTimeData): MutableMap<FactorType, Boolean> { + val res = mutableMapOf<FactorType, Boolean>() + config.factorFilter.mainList().forEach { f -> + if (p?.getByFactorType(f) == null || n.getByFactorType(f) == null) { + res[f] = (false) + return@forEach + } + val pValue = p.getByFactorType(f)!! + val nValue = n.getByFactorType(f)!! + // 璁$畻鍚庝竴涓暟鎹浉姣斾簬鍓嶄竴涓暟鎹殑鍙樺寲鐜� + val r = (nValue - pValue) / pValue + // 褰撳彉鍖栫巼涓烘鏁帮紙鍗虫暟鎹笂鍗囨椂锛夛紝涓斿ぇ浜庤瀹氬�兼椂锛岃涓烘槸寮傚父鎯呭喌 + val b1 = r >= (2 * config.mutationRate) + val b2 = r >= config.mutationRate + if (b1) special = true + res[f] = (b1 || b2) + } + + return res + } + + override fun judgeExceptionCount(tag: Tag): Boolean { + // 棣栦釜鏁版嵁娌℃湁鍓嶄竴涓暟鎹弬鐓э紝涓嶇畻寮傚父鍊硷紝鏈�鍚庝竴涓暟鎹槸鍒ゆ柇缁撴潫鐨勬甯稿�硷紝鍥犳寮傚父鏁版嵁涓暟鐨勮绠椾笅鏍囦负sIndex鍜宔Index + val sIndex = tag.sIndex + val eIndex = tag.eIndex - 1 + + val b1 = special && (eIndex - sIndex) >= (config.mutationNum / 2) + val b2 = (eIndex - sIndex) >= config.mutationNum + special = false + return b1 || b2 + } + + override fun needCut(tag: Tag): Boolean { + // 鎸夌収鏃堕暱鍜岃窛绂婚檺鍒跺皢寮傚父鎴彇 + if (tag.exceptionData.isEmpty()) return false + + val se = tag.exceptionData.first() + val ee = tag.exceptionData.last() + + val sTime = LocalDateTime.ofInstant(se.dataTime?.toInstant(), ZoneId.systemDefault()) + val eTime = LocalDateTime.ofInstant(ee.dataTime?.toInstant(), ZoneId.systemDefault()) + val duration = Duration.between(sTime, eTime).toMinutes() + // 鏁版嵁閲囨牱鐨勬椂闀胯秴杩囬檺鍒舵椂锛岄渶瑕佹埅鍙� + val b1 = duration > config.timeLimit + + // 璧拌埅鏁版嵁鐨勮窛绂昏秴杩囬檺鍒舵椂锛岄渶瑕佹埅鍙� + val b2 = if (se.longitude == null || se.latitude == null || ee.longitude == null || ee.latitude == null) { + false + } else { + val distance = MapUtil.getDistance( + se.longitude!!.toDouble(), se.latitude!!.toDouble(), ee.longitude!! + .toDouble(), ee.latitude!!.toDouble() + ) + distance > config.distanceLimit + } + + return b1 || b2 + } +} \ No newline at end of file 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 new file mode 100644 index 0000000..86ef036 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/RealTimeExceptionResult.kt @@ -0,0 +1,105 @@ +package com.flightfeather.uav.biz.sourcetrace.model + +import com.flightfeather.uav.biz.FactorFilter +import com.flightfeather.uav.biz.dataanalysis.BaseExceptionResult +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionType +import com.flightfeather.uav.common.utils.DateUtil +import com.flightfeather.uav.domain.entity.BaseRealTimeData +import com.flightfeather.uav.domain.entity.SceneInfo +import com.flightfeather.uav.domain.entity.avg +import com.flightfeather.uav.socket.eunm.FactorType +import java.math.BigDecimal + +/** + * + * @date 2025/5/13 + * @author feiyu02 + */ +class RealTimeExceptionResult() : BaseExceptionResult() { + + var deviceCode: String? = null + + var exception: String? = null + var exceptionType: Int? = null + + var factorId: Int? = null + var factorName: String? = null + var subFactorId: List<Int>? = null + var subFactorName: List<String>? = null + var selectedFactor: FactorFilter.SelectedFactor? = null + + var startTime: String? = null + var endTime: String? = null + + var startData: Float? = null + var endData: Float? = null + var avg: Float? = null + var min: Float? = null + var max: Float? = null + + // 寮傚父鏁版嵁锛屽ご灏惧彲鑳藉寘鍚竴瀹氶噺鐨勫亸绉� + var dataList: MutableList<BaseRealTimeData> = mutableListOf() + + // 涓績鐐圭粡绾害 + var longitude: BigDecimal? = null + var latitude: BigDecimal? = null + + // 婧簮浼佷笟 + var relatedSceneList: List<SceneInfo?>? = null + + constructor( + start: BaseRealTimeData, + end: BaseRealTimeData?, + factor: FactorFilter.SelectedFactor, + exceptionData: List<BaseRealTimeData>, + eType: ExceptionType, + ) : this() { + deviceCode = start.deviceCode + exception = eType.des + exceptionType = eType.value + factorId = factor.main.value + factorName = factor.main.des + subFactorId = factor.subs.map { it.value } + subFactorName = factor.subs.map { it.des } + selectedFactor = factor + startTime = DateUtil.instance.dateToString(start.dataTime, DateUtil.DateStyle.HH_MM_SS) + endTime = DateUtil.instance.dateToString(end?.dataTime, DateUtil.DateStyle.HH_MM_SS) ?: startTime + startData = start.getByFactorType(factor.main) + endData = end?.getByFactorType(factor.main) ?: startData + + val avgData = exceptionData.avg() + // 姹傚彇姹℃煋鏁版嵁鐨勪腑蹇冨潗鏍� + longitude = avgData.longitude + latitude = avgData.latitude + // 姹傚彇涓绘薄鏌撳洜瀛愮殑鍧囧�煎拰鑼冨洿 + val s = dataSummary(exceptionData, factor.main) + avg = s.first + min = s.second + max = s.third + + exceptionData.forEach { dataList.add(it) } + } + + private fun dataSummary( + exceptionData: List<BaseRealTimeData?>, + factorType: FactorType, + ): Triple<Float, Float, Float> { + var min = -1f + var max = -1f + var total = 0f + var count = 0 + exceptionData.forEach { + val value = it?.getByFactorType(factorType) ?: return@forEach + if (min == -1f || min > value) { + min = value + } + if (max == -1f || max < value) { + max = value + } + total += value + count++ + } + val avg = if (count == 0) 0f else total / count + return Triple(avg, min, max) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/common/utils/GsonUtils.kt b/src/main/kotlin/com/flightfeather/uav/common/utils/GsonUtils.kt index 387be46..5585a60 100644 --- a/src/main/kotlin/com/flightfeather/uav/common/utils/GsonUtils.kt +++ b/src/main/kotlin/com/flightfeather/uav/common/utils/GsonUtils.kt @@ -1,8 +1,9 @@ package com.flightfeather.uav.common.utils import com.google.gson.Gson +import com.google.gson.GsonBuilder import com.google.gson.JsonParser -import java.util.ArrayList +import java.time.LocalDateTime /** * @author riku @@ -11,6 +12,10 @@ */ object GsonUtils { + val gson: Gson = GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss") + .registerTypeAdapter(LocalDateTime::class.java, LocalDateTimeAdapter()) + .create() + fun getNoteJsonString(jsonString: String, note: String): String { if (jsonString.isEmpty()) { throw RuntimeException("getNoteJsonString jsonString empty") diff --git a/src/main/kotlin/com/flightfeather/uav/common/utils/LocalDateTimeAdapter.java b/src/main/kotlin/com/flightfeather/uav/common/utils/LocalDateTimeAdapter.java new file mode 100644 index 0000000..73ac7ad --- /dev/null +++ b/src/main/kotlin/com/flightfeather/uav/common/utils/LocalDateTimeAdapter.java @@ -0,0 +1,30 @@ +package com.flightfeather.uav.common.utils; + +import com.google.gson.*; + +import java.lang.reflect.Type; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * LocalDateTime绫诲瀷鐨勬椂闂存牸寮忓簭鍒楀寲鍜屽弽搴忓垪鍖栫被 + * by hc 2024.12.6 + */ +public class LocalDateTimeAdapter implements JsonDeserializer<LocalDateTime>, JsonSerializer<LocalDateTime> { + private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + @Override + public JsonElement serialize(LocalDateTime src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(dateTimeFormatter.format(src)); + } + + @Override + public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + try { + return LocalDateTime.parse(json.getAsString(), dateTimeFormatter); + } catch (Exception e) { + throw new JsonParseException(e); + } + } +} + diff --git a/src/main/kotlin/com/flightfeather/uav/common/utils/MapUtil.kt b/src/main/kotlin/com/flightfeather/uav/common/utils/MapUtil.kt index e3e9917..cdcfcb9 100644 --- a/src/main/kotlin/com/flightfeather/uav/common/utils/MapUtil.kt +++ b/src/main/kotlin/com/flightfeather/uav/common/utils/MapUtil.kt @@ -51,6 +51,7 @@ /** * 鑾峰彇涓ょ粡绾害闂寸殑璺濈 + * @return 杩斿洖涓ょ偣闂磋窛绂伙紝鍗曚綅锛氱背 */ fun getDistance(lng1: Double, lat1: Double, lng2: Double, lat2: Double): Double { // lat1 = lat1 || 0; @@ -167,7 +168,7 @@ * 鍒ゆ柇鍧愭爣鐐规槸鍚﹀湪澶氳竟褰㈠唴閮� */ fun isPointInPolygon(point: Pair<Double, Double>, polygon: List<Pair<Double, Double>>): Boolean { - if (polygon.size < 4) throw IllegalArgumentException("not a polygon") + if (polygon.size < 3) throw IllegalArgumentException("not a polygon") // 涓嶅湪鍥涜嚦鑼冨洿鍐咃紝鍒欎竴瀹氫笉鍦ㄥ杈瑰舰鍐� if (!inBBox(point, polygon)) return false diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt b/src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt index d4d315c..741a06a 100644 --- a/src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt +++ b/src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt @@ -10,6 +10,8 @@ import java.time.ZoneId import java.util.* import javax.persistence.Column +import javax.persistence.GeneratedValue +import javax.persistence.GenerationType import javax.persistence.Id import kotlin.math.atan import kotlin.math.cos @@ -21,6 +23,7 @@ */ open class BaseRealTimeData { @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Int? = null @Column(name = "device_code") diff --git a/src/main/kotlin/com/flightfeather/uav/domain/repository/AirDataRep.kt b/src/main/kotlin/com/flightfeather/uav/domain/repository/AirDataRep.kt index 1460a05..20ae724 100644 --- a/src/main/kotlin/com/flightfeather/uav/domain/repository/AirDataRep.kt +++ b/src/main/kotlin/com/flightfeather/uav/domain/repository/AirDataRep.kt @@ -1,5 +1,6 @@ package com.flightfeather.uav.domain.repository +import com.flightfeather.uav.domain.entity.BaseRealTimeData import com.flightfeather.uav.domain.entity.RealTimeData import com.flightfeather.uav.lightshare.bean.DataVo import com.flightfeather.uav.socket.bean.AirDataPackage @@ -26,6 +27,6 @@ */ fun savePrepData(dataList: List<RealTimeData>): Int - fun savePrepData2(dataList: List<DataVo>): Int + fun savePrepData2(dataList: List<DataVo>): List<BaseRealTimeData> } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/domain/repository/impl/AirDataRepImpl.kt b/src/main/kotlin/com/flightfeather/uav/domain/repository/impl/AirDataRepImpl.kt index 6f2bdc1..5008d5b 100644 --- a/src/main/kotlin/com/flightfeather/uav/domain/repository/impl/AirDataRepImpl.kt +++ b/src/main/kotlin/com/flightfeather/uav/domain/repository/impl/AirDataRepImpl.kt @@ -127,8 +127,8 @@ return count } - override fun savePrepData2(dataList: List<DataVo>): Int { - var count = 0 + override fun savePrepData2(dataList: List<DataVo>): List<BaseRealTimeData> { + val res = mutableListOf<BaseRealTimeData>() dataList.forEach {vo -> when (UWDeviceType.getType(vo.deviceCode)) { UWDeviceType.VEHICLE -> { @@ -139,7 +139,7 @@ calibration(d, UWDeviceType.VEHICLE) /***************************************************************************************************/ realTimeDataVehicleMapper.insert(d) - count++ + res.add(d) } UWDeviceType.UAV -> { val d = RealTimeDataUav() @@ -164,7 +164,7 @@ } /***************************************************************************************************/ realTimeDataUavMapper.insert(d) - count++ + res.add(d) } UWDeviceType.GRID -> { val d = RealTimeDataGrid() @@ -196,7 +196,7 @@ // d.h2s = d.h2s?.let { sqrt(it) * 2 } /**************************************************************************/ realTimeDataGridMapper.insert(d) - count++ + res.add(d) } UWDeviceType.BOAT -> { @@ -204,7 +204,7 @@ else -> Unit } } - return count + return res } private fun dataTransform(vo: RealTimeData, bean: BaseRealTimeData) { diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt index 8648d99..771ff89 100644 --- a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt +++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt @@ -395,7 +395,7 @@ println("褰撳墠椤垫暟锛�$page") val dataList = res.data ?: emptyList() val result = epwDataPrep.mDataPrep2(dataList) - count += airDataRep.savePrepData2(result) + count += airDataRep.savePrepData2(result).size page++ } diff --git a/src/main/kotlin/com/flightfeather/uav/socket/UnderwaySocketServer.kt b/src/main/kotlin/com/flightfeather/uav/socket/UnderwaySocketServer.kt index c9d98ea..1abff63 100644 --- a/src/main/kotlin/com/flightfeather/uav/socket/UnderwaySocketServer.kt +++ b/src/main/kotlin/com/flightfeather/uav/socket/UnderwaySocketServer.kt @@ -1,5 +1,7 @@ package com.flightfeather.uav.socket +import com.flightfeather.uav.socket.handler.ServerHandler +import com.flightfeather.uav.socket.handler.UnderwayWebSocketServerHandler import com.flightfeather.uav.socket.processor.BaseProcessor import io.netty.bootstrap.ServerBootstrap import io.netty.channel.ChannelHandler @@ -9,15 +11,22 @@ import io.netty.channel.socket.nio.NioServerSocketChannel import io.netty.channel.socket.nio.NioSocketChannel import io.netty.handler.codec.LineBasedFrameDecoder +import io.netty.handler.codec.http.HttpObjectAggregator +import io.netty.handler.codec.http.HttpServerCodec +import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler import io.netty.handler.codec.string.StringDecoder import io.netty.handler.codec.string.StringEncoder +import org.springframework.stereotype.Component import java.nio.charset.Charset /********************************************************************************* * 璧拌埅鐩戞祴鏁版嵁socket闀胯繛鎺ユ湇鍔$ * 鐢ㄤ簬鎺ユ敹瑙f瀽璧拌埅鐩戞祴鏁版嵁锛屽墠绔洃娴嬭澶囩洰鍓嶅寘鎷溅杞借蛋鑸�佹棤浜烘満璧拌埅浠ュ強鏃犱汉鑸硅蛋鑸笁绉嶇被鍨� * *******************************************************************************/ -class UnderwaySocketServer { +@Component +class UnderwaySocketServer( + private val underwayWebSocketServerHandler:UnderwayWebSocketServerHandler +) { private val bossGroup = NioEventLoopGroup() private val workerGroup = NioEventLoopGroup() @@ -28,6 +37,10 @@ fun startElectricServer(port: Int, processor: BaseProcessor) { electricServer(processor)?.bind(port)?.sync() + } + + fun startWebSocketServer(port: Int, processor: BaseProcessor) { + webSocketServer(processor)?.bind(port)?.sync() } fun stopServer() { @@ -75,4 +88,17 @@ ?.addLast(ServerHandler(processor)) } }) + + /** + * 澶氬弬鏁拌蛋鑸湇鍔$ + */ + private fun webSocketServer(processor: BaseProcessor):ServerBootstrap? = newServer(object : ChannelInitializer<NioSocketChannel>() { + override fun initChannel(p0: NioSocketChannel?) { + p0?.pipeline() + ?.addLast(HttpServerCodec()) + ?.addLast(HttpObjectAggregator(65535)) + ?.addLast(WebSocketServerProtocolHandler("/ws")) + ?.addLast(underwayWebSocketServerHandler) + } + }) } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/socket/handler/BaseHandler.kt b/src/main/kotlin/com/flightfeather/uav/socket/handler/BaseHandler.kt new file mode 100644 index 0000000..90808a1 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/uav/socket/handler/BaseHandler.kt @@ -0,0 +1,59 @@ +package com.flightfeather.uav.socket.handler + +import io.netty.channel.ChannelHandlerContext +import io.netty.channel.ChannelInboundHandlerAdapter +import java.text.SimpleDateFormat +import java.util.* + +/** + * socket娑堟伅澶勭悊绉熀绫� + * @date 2025/5/13 + * @author feiyu02 + */ +abstract class BaseHandler : ChannelInboundHandlerAdapter() { + + abstract var tag: String + + override fun channelRegistered(ctx: ChannelHandlerContext?) { + super.channelRegistered(ctx) + println("------銆�${tag}銆慖P杩炴帴锛歔ip:${ctx?.channel()?.remoteAddress()}] ${ + SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format( + Date() + )}") +// ctx?.fireChannelActive() + } + + override fun channelActive(ctx: ChannelHandlerContext?) { + println("------銆�${tag}銆慖P婵�娲伙細[ip:${ctx?.channel()?.remoteAddress()}] ${ + SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format( + Date() + )}") + super.channelActive(ctx) + } + + override fun channelRead(ctx: ChannelHandlerContext?, msg: Any?) { + super.channelRead(ctx, msg) + println("------銆�${tag}銆戞敹鍒扮殑鍘熷鏁版嵁锛歔ip:${ctx?.channel()?.remoteAddress()}] ${ + SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format( + Date() + )}") + } + + override fun channelReadComplete(ctx: ChannelHandlerContext?) { + super.channelReadComplete(ctx) + } + + override fun channelInactive(ctx: ChannelHandlerContext?) { + println("------銆�${tag}銆戠鍙f湁IP涓嶆椿鍔細[ip:${ctx?.channel()?.remoteAddress()}] ${ + SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format( + Date() + )}") + super.channelInactive(ctx) + } + + @Deprecated("Deprecated in Java") + override fun exceptionCaught(ctx: ChannelHandlerContext?, cause: Throwable?) { + cause?.printStackTrace() + ctx?.close() + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/socket/ServerHandler.kt b/src/main/kotlin/com/flightfeather/uav/socket/handler/ServerHandler.kt similarity index 97% rename from src/main/kotlin/com/flightfeather/uav/socket/ServerHandler.kt rename to src/main/kotlin/com/flightfeather/uav/socket/handler/ServerHandler.kt index 61a2d8c..30be29a 100644 --- a/src/main/kotlin/com/flightfeather/uav/socket/ServerHandler.kt +++ b/src/main/kotlin/com/flightfeather/uav/socket/handler/ServerHandler.kt @@ -1,10 +1,9 @@ -package com.flightfeather.uav.socket +package com.flightfeather.uav.socket.handler import com.flightfeather.uav.socket.processor.BaseProcessor import io.netty.channel.ChannelHandlerContext import io.netty.channel.ChannelInboundHandlerAdapter import io.netty.util.AttributeKey -import org.ietf.jgss.MessageProp import java.lang.StringBuilder import java.text.SimpleDateFormat import java.util.* diff --git a/src/main/kotlin/com/flightfeather/uav/socket/handler/UnderwayWebSocketServerHandler.kt b/src/main/kotlin/com/flightfeather/uav/socket/handler/UnderwayWebSocketServerHandler.kt new file mode 100644 index 0000000..0e912d3 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/uav/socket/handler/UnderwayWebSocketServerHandler.kt @@ -0,0 +1,55 @@ +package com.flightfeather.uav.socket.handler + +import io.netty.channel.ChannelHandlerContext +import io.netty.handler.codec.http.websocketx.TextWebSocketFrame +import org.springframework.stereotype.Component + +/** + * + * @date 2025/5/13 + * @author feiyu02 + */ +@Component +class UnderwayWebSocketServerHandler : BaseHandler() { + + private val sessionPool = mutableMapOf<String?, ChannelHandlerContext?>() + + override var tag: String = "UAV-WS" + + override fun channelRegistered(ctx: ChannelHandlerContext?) { + super.channelRegistered(ctx) + // 灏嗚繛鎺ュ瓨鍌� + if (!sessionPool.containsKey(ctx?.name())) { + sessionPool[ctx?.name()] = ctx + } + } + + override fun channelRead(ctx: ChannelHandlerContext?, msg: Any?) { + super.channelRead(ctx, msg) + + when (msg) { + is TextWebSocketFrame->{ + println(msg.text()) + ctx?.channel()?.writeAndFlush(msg) + } + } + } + + override fun channelInactive(ctx: ChannelHandlerContext?) { + super.channelInactive(ctx) + // 灏嗚繛鎺ョЩ闄� + if (sessionPool.containsKey(ctx?.name())) { + sessionPool.remove(ctx?.name()) + } + } + + fun send() { + + } + + fun broadcast(msg: String) { + sessionPool.forEach { t, u -> + u?.channel()?.writeAndFlush(TextWebSocketFrame(msg)) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/socket/processor/UnderwayProcessor.kt b/src/main/kotlin/com/flightfeather/uav/socket/processor/UnderwayProcessor.kt index 201bfe4..a649598 100644 --- a/src/main/kotlin/com/flightfeather/uav/socket/processor/UnderwayProcessor.kt +++ b/src/main/kotlin/com/flightfeather/uav/socket/processor/UnderwayProcessor.kt @@ -1,12 +1,20 @@ package com.flightfeather.uav.socket.processor +import com.flightfeather.uav.biz.FactorFilter +import com.flightfeather.uav.biz.sourcetrace.RealTimeExceptionAnalysisController +import com.flightfeather.uav.common.location.LocationRoadNearby +import com.flightfeather.uav.domain.entity.BaseRealTimeData import com.flightfeather.uav.model.epw.EPWDataPrep import com.flightfeather.uav.domain.repository.AirDataRep +import com.flightfeather.uav.domain.repository.RealTimeDataRep +import com.flightfeather.uav.domain.repository.SegmentInfoRep import com.flightfeather.uav.socket.bean.AirDataPackage import com.flightfeather.uav.socket.decoder.AirDataDecoder import com.flightfeather.uav.socket.decoder.DataPackageDecoder import com.flightfeather.uav.socket.eunm.AirCommandUnit +import com.flightfeather.uav.socket.eunm.FactorType import com.flightfeather.uav.socket.eunm.UWDeviceType +import com.flightfeather.uav.socket.handler.UnderwayWebSocketServerHandler import io.netty.channel.ChannelHandlerContext import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component @@ -21,16 +29,17 @@ */ @Component -class UnderwayProcessor : BaseProcessor() { +class UnderwayProcessor( + private val airDataRep: AirDataRep, + private val realTimeDataRep: RealTimeDataRep, + private val locationRoadNearby: LocationRoadNearby, + private val segmentInfoRep: SegmentInfoRep, + private val underwayWebSocketServerHandler: UnderwayWebSocketServerHandler, +) : BaseProcessor() { companion object { - private lateinit var instance: UnderwayProcessor - private const val TAG = "UAV" } - - @Autowired - lateinit var airDataRep: AirDataRep private val airDataDecoder = AirDataDecoder.instance private val dataPackageDecoder = DataPackageDecoder() @@ -38,10 +47,24 @@ // 鏁版嵁棰勫鐞嗗嚱鏁� private val dataProcessMap = mutableMapOf<String?, EPWDataPrep>() - @PostConstruct - fun init() { - instance = this - } + // 瀹炴椂璧拌埅姹℃煋婧簮澶勭悊鍣� + private val realTimeExceptionAnalysisController = + RealTimeExceptionAnalysisController( + realTimeDataRep, + locationRoadNearby, + segmentInfoRep, + underwayWebSocketServerHandler, + FactorFilter.builder() +// .withMain(FactorType.NO2) + .withMain(FactorType.CO) +// .withMain(FactorType.H2S) +// .withMain(FactorType.SO2) +// .withMain(FactorType.O3) + .withMain(FactorType.PM25) + .withMain(FactorType.PM10) + .withMain(FactorType.VOC) + .create() + ) override var tag: String = "璧拌埅鐩戞祴" @@ -53,7 +76,11 @@ //淇濆瓨 deviceSession.saveDevice(packageData.deviceCode, ctx) saveToTxt(msg) - saveToDataBase(packageData) + saveToDataBase(packageData)?.takeIf { it.isNotEmpty() }?.get(0)?.let { + // 灏嗚蛋鑸暟鎹紶鍏ュ紓甯稿鐞嗗櫒 + realTimeExceptionAnalysisController.addOneData(it) + } + } else { println("------${TAG}鏁版嵁BCC鏍¢獙澶辫触锛岃垗寮� [${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}]") } @@ -62,21 +89,23 @@ /** * 淇濆瓨鑷虫暟鎹簱 */ - fun saveToDataBase(dataPackage: AirDataPackage) { + fun saveToDataBase(dataPackage: AirDataPackage): List<BaseRealTimeData>? { when (dataPackage.commandUnit) { AirCommandUnit.AirData.value -> { // 浠son鏍煎紡瀛樺偍鍘熷鏁版嵁 - instance.airDataRep.saveAirData(dataPackage) + airDataRep.saveAirData(dataPackage) // 杩涜棰勫鐞嗗悗锛屽瓨鍌ㄨ嚦瀵瑰簲鏁版嵁琛� if (!dataProcessMap.containsKey(dataPackage.deviceCode)) { // 姣忓彴璁惧鏈夊崟鐙殑鏁版嵁棰勫鐞嗗璞� dataProcessMap[dataPackage.deviceCode] = EPWDataPrep(UWDeviceType.getType(dataPackage.deviceCode)) } - dataProcessMap[dataPackage.deviceCode]?.run { + return dataProcessMap[dataPackage.deviceCode]?.run { val list = this.mDataPrep2(dataPackage)// 鏁版嵁骞虫粦澶勭悊 - instance.airDataRep.savePrepData2(list)// 鎸夌収璁惧绫诲瀷瀛樺偍鑷冲搴旀暟鎹〃 + airDataRep.savePrepData2(list)// 鎸夌収璁惧绫诲瀷瀛樺偍鑷冲搴旀暟鎹〃 } } + + else -> return emptyList() } } @@ -108,7 +137,7 @@ fun encodeToBytes(msg: String): ByteArray { val list = msg.split(" ") val bytes = ByteArray(list.size) - for (i in 0 until list.size) { + for (i in list.indices) { bytes[i] = list[i].toInt(16).toByte() } -- Gitblit v1.9.3