src/main/java/com/flightfeather/monitor/MonitorApplication.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/flightfeather/monitor/analysis/dust/RiskAnalysisController.kt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/flightfeather/monitor/analysis/dust/risk/DustRiskAnalysis.kt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/flightfeather/monitor/analysis/dust/risk/DustRiskMonthAnalysis.kt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/flightfeather/monitor/domain/ds1/repository/DustExceptionDataRep.kt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/flightfeather/monitor/domain/ds1/repository/DustStatisticsValueRep.kt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/flightfeather/monitor/domain/ds1/repository/RiskValueRep.kt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/test/java/com/flightfeather/monitor/analysis/dust/RiskAnalysisControllerTest.kt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/main/java/com/flightfeather/monitor/MonitorApplication.java
@@ -2,6 +2,7 @@ import com.flightfeather.monitor.scheduledtasks.TaskController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -14,7 +15,12 @@ @Bean public ApplicationRunner runner() { return args -> taskController.run(); return new ApplicationRunner() { @Override public void run(ApplicationArguments args) throws Exception { // taskController.run(); } }; } public static void main(String[] args) { src/main/java/com/flightfeather/monitor/analysis/dust/RiskAnalysisController.kt
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,109 @@ package com.flightfeather.monitor.analysis.dust import com.flightfeather.monitor.analysis.dust.risk.* import com.flightfeather.monitor.domain.ds1.repository.* import com.flightfeather.monitor.enumration.dust.DeviceStatus import com.flightfeather.monitor.utils.DateUtil import org.springframework.stereotype.Component import java.time.LocalDate import java.time.LocalDateTime import java.time.ZoneId /** * æ°æ®é£é©åææ§å¶å¨ */ @Component class RiskAnalysisController( private val dustExceptionSettingRep: DustExceptionSettingRep, private val riskValueRep: RiskValueRep, private val dustSiteStatusRep: DustSiteStatusRep, private val dustSiteDataRep: DustSiteDataRep, private val dustExceptionDataRep: DustExceptionDataRep, private val dustStatisticValueRep: DustStatisticsValueRep, ) { private var running1 = false private var running2 = false private var taskDaily: DustRiskAnalysis? = null private var taskMonthly: DustRiskMonthAnalysis? = null fun init() { dustExceptionSettingRep.findLatestSetting("éå±±åº")?.let { taskDaily = DustRiskAnalysis(it) taskMonthly = DustRiskMonthAnalysis(it) } } fun autoRunDaily() { val data = riskValueRep.findLatestData("day") val yesterday = LocalDate.now().minusDays(1) if (data == null) { runDaily(yesterday) } else { val date = LocalDateTime.ofInstant(data.lst.toInstant(), ZoneId.systemDefault()) val sT = if (date.hour == 0 && date.minute == 0 && date.second == 0) { date.toLocalDate() } else { date.plusDays(1).toLocalDate() } val du = DateUtil.findDurationDate(sT, yesterday) du.forEach { runDaily(it) } } } fun autoRunMonthly() { val data = riskValueRep.findLatestData("month") val lastMonth = LocalDate.now().minusMonths(1).withDayOfMonth(1) if (data == null) { runMonthly(lastMonth) } else { val date = LocalDateTime.ofInstant(data.lst.toInstant(), ZoneId.systemDefault()) val sT = date.plusMonths(1).toLocalDate() val du = DateUtil.findDurationMonth(sT, lastMonth) du.forEach { runMonthly(it) } } } fun runDaily(date: LocalDate) { running1 = true taskDaily?.init() // è·åææå½åä¸çº¿ååè¿çè®¾å¤ dustSiteStatusRep.select(listOf(DeviceStatus.ONLINE, DeviceStatus.STOP)).forEach { s -> s?.let { taskDaily?.roundInit() val dustSiteDataList = dustSiteDataRep.select(s.mnCode, date) val dustExceptionDataList = dustExceptionDataRep.select(s.mnCode, date) val dustStatisticValueList = dustStatisticValueRep.select(s.mnCode, date) if (dustStatisticValueList.isEmpty()) return@forEach taskDaily?.roundCal(dustStatisticValueList[0]!!, dustSiteDataList, dustExceptionDataList) } } // ææåæç»æå ¥åº if (taskDaily?.resultList?.isNotEmpty() == true) { riskValueRep.insert(taskDaily?.resultList!!) } running1 = false } fun runMonthly(date: LocalDate) { running2 = true taskMonthly?.init() dustSiteStatusRep.select(listOf(DeviceStatus.ONLINE, DeviceStatus.STOP)).forEach { s -> s?.let { taskMonthly?.roundInit() val riskValueList = riskValueRep.select(s.mnCode, date) taskMonthly?.roundCal(riskValueList) } } // ææåæç»æå ¥åº if (taskMonthly?.resultList?.isNotEmpty() == true) { riskValueRep.insert(taskMonthly?.resultList!!) } running2 = false } } src/main/java/com/flightfeather/monitor/analysis/dust/risk/DustRiskAnalysis.kt
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,133 @@ package com.flightfeather.monitor.analysis.dust.risk import com.flightfeather.monitor.domain.ds1.entity.* import com.flightfeather.monitor.enumration.dust.ExceptionType /** * æ¬å°çæµæ°æ®é£é©åæåºç±» */ class DustRiskAnalysis(val config: DustExceptionSetting) { //åæç»æ val resultList = mutableListOf<RiskValue>() /** * åå§å */ fun init() { resultList.clear() } /** * æ¯è½®æ¬¡çåå§å */ fun roundInit() { resultList.add(RiskValue()) } /** * æ¯è½®æ¬¡çé£é©å¼è®¡ç® */ fun roundCal(data: DustStatisticsValue, list: List<DustSiteData?>, dList: List<DustExceptionData?>) { if (resultList.isEmpty()) throw IllegalStateException("ç»æéresultListä¸è½ä¸ºç©ºï¼") val res = resultList.last() riskOnlineRate(res, data) riskValidRate(res, data) riskExceedRate(res, list) riskExceptionRepetitionRate(res, dList) riskExceptionType(res, dList) onDone(res) } /** * å¨çº¿çé£é©å¼ */ fun riskOnlineRate(riskValue: RiskValue, data: DustStatisticsValue) { val dayOnline = data.dayOnline.substring(0, data.dayOnline.lastIndex).toDouble() / 100 riskValue.onlineRisk = 1 - dayOnline } /** * ææçé£é©å¼ */ fun riskValidRate(riskValue: RiskValue, data: DustStatisticsValue) { val dayValid = data.dayValid.substring(0, data.dayValid.lastIndex).toDouble() / 100 riskValue.validRisk = 1 - dayValid } /** * è¶ æ é£é©å¼ */ fun riskExceedRate(riskValue: RiskValue, list: List<DustSiteData?>) { // æ¥è¶ æ æ¬¡æ°/7ï¼å¤§äº1mg/m³ï¼å°äº2mg/mÂ³ï¼ var v1 = 0 // æ¥è¶ æ æ¬¡æ°/2ï¼å¤§äº2mg/mÂ³ï¼ var v2 = 0 // æ¥ä¸´è¿è¶ æ æ¬¡æ°/7 var v3 = 0 list.forEach {d -> if (d == null) return@forEach when { d.dustValue >= 2.0 -> v2++ d.dustValue >= 1.0 && d.dustValue < 2.0 -> v1++ d.dustValue >= config.nearExceedLowValue && d.dustValue < config.nearExceedHighValue -> v3++ } } // åçæå¤§å¼ä¸º3æå°å¼ä¸º0ï¼ä¸è¿°ä¹åé¤ä»¥3ï¼ç»ææå¤§å¼ä¸º1æå°å¼ä¸º0ï¼å³ä¸ºæ¥è¶ æ é£é©å¼ val r = (v1 + v2 + v3) / 3.0 riskValue.exceedRisk = if (r > 1) 1.0 else r } /** * å ¸åå¼å¸¸å¤ç°ç */ fun riskExceptionRepetitionRate(riskValue: RiskValue, list: List<DustExceptionData?>) { //1ãé对é级çªåå¼å¸¸ã临è¿è¶ æ å¼å¸¸ãåæ¥è¶ æ æ¬¡æ°ä¸´çå¼å¸¸çæå®æ¶æ®µï¼å¦24å°æ¶å ï¼éå¤åºç°æ¦çæ¥ç»¼åå¤å®å ¸åå¼å¸¸å¤ç°çï¼ //2ãæ¥é级çªåå¼å¸¸å¤ç°çï¼E4ï¼ï¼ï¼N4-1ï¼/4ï¼ æå¤§ä¸º1ï¼æå°ä¸º0 //3ãæ¥ä¸´è¿è¶ æ å¼å¸¸å¤ç°çï¼E5ï¼ï¼ï¼N5-1ï¼/3ï¼ æå¤§ä¸º1ï¼æå°ä¸º0 //4ãæ¥è¶ æ æ¬¡æ°ä¸´çå¼å¸¸å¤ç°çï¼E6ï¼ï¼ï¼N6-1ï¼/2ï¼ æå¤§ä¸º1ï¼æå°ä¸º0 //5ãæ¥å ¸åå¼å¸¸å¤ç°ç: åE4ãE5ãE6çåï¼æå¤§ä¸º1ï¼æå°ä¸º0 //6ãæå ¸åå¼å¸¸å¤ç°çï¼å½æå åæ¥å ¸åå¼å¸¸å¤ç°ççå/彿天æ°ï¼æå¤§ä¸º1ï¼æå°ä¸º0 var v1 = 0 var v2 = 0 var v3 = 0 list.forEach { d-> if (d == null) return@forEach when (d.exceptionType) { ExceptionType.TYPE4.value -> v1++ ExceptionType.TYPE5.value -> v2++ ExceptionType.TYPE6.value -> v3++ } } val e1 = upperLimit((v1 - 1) / 4.0) val e2 = upperLimit((v2 - 1) / 3.0) val e3 = upperLimit((v3 - 1) / 2.0) riskValue.typicalExceptionRepetitionRate = upperLimit(e1 + e2 + e3) } /** * å¼å¸¸ç±»åèéç */ fun riskExceptionType(riskValue: RiskValue, list: List<DustExceptionData?>) { // æ¥å¼å¸¸ç±»åèéçï¼å½æ¥åºç°çä¸åå¼å¸¸ç±»å个æ°/6ï¼æå¤§ä¸º1ï¼æå°ä¸º0 //2ãæå¼å¸¸ç±»åèéçï¼å½æå 忥å¼å¸¸ç±»åèéççå/彿天æ°ï¼æå¤§ä¸º1ï¼æå°ä¸º0 // å ¶ä»æ¶æ®µä»¥æ¤ç±»æ¨ï¼æ°æ®è¶ ä½ãé¿æ¶é´æ æ³¢å¨ç两类å¼å¸¸æä¸çº³å ¥åæï¼è¥çº³å ¥åæååæ¯ä¸º8 val exceptionTypes = mutableListOf<Int>() list.forEach { d -> if (d == null) return@forEach if (!exceptionTypes.contains(d.exceptionType)) { if (d.exceptionType != ExceptionType.TYPE1.value && d.exceptionType != ExceptionType.TYPE3.value) { exceptionTypes.add(d.exceptionType) } } } riskValue.exceptionTypeAggregation = exceptionTypes.size / 6.0 } fun onDone(riskValue: RiskValue) { riskValue.type = "day" } private fun upperLimit(d:Double):Double = if (d > 1) 1.0 else d } src/main/java/com/flightfeather/monitor/analysis/dust/risk/DustRiskMonthAnalysis.kt
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,74 @@ package com.flightfeather.monitor.analysis.dust.risk import com.flightfeather.monitor.domain.ds1.entity.* class DustRiskMonthAnalysis(val config: DustExceptionSetting) { //åæç»æ val resultList = mutableListOf<RiskValue>() /** * åå§å */ fun init() { resultList.clear() } /** * æ¯è½®æ¬¡çåå§å */ fun roundInit() { resultList.add(RiskValue()) } /** * æ¯è½®æ¬¡çé£é©å¼è®¡ç® */ fun roundCal(list: List<RiskValue?>) { if (resultList.isEmpty()) throw IllegalStateException("ç»æéresultListä¸è½ä¸ºç©ºï¼") val res = resultList.last() riskOnlineRate(res, list) riskValidRate(res, list) riskExceedRate(res, list) riskExceptionRepetitionRate(res, list) riskExceptionType(res, list) onDone(res) } fun riskOnlineRate(riskValue: RiskValue, list: List<RiskValue?>) { riskValue.onlineRisk = avg(list) { it.onlineRisk } } fun riskValidRate(riskValue: RiskValue, list: List<RiskValue?>) { riskValue.validRisk = avg(list) { it.validRisk } } fun riskExceedRate(riskValue: RiskValue, list: List<RiskValue?>) { riskValue.exceedRisk = avg(list) { it.exceedRisk } } fun riskExceptionRepetitionRate(riskValue: RiskValue, list: List<RiskValue?>) { riskValue.typicalExceptionRepetitionRate = avg(list) { it.typicalExceptionRepetitionRate } } fun riskExceptionType(riskValue: RiskValue, list: List<RiskValue?>) { riskValue.exceptionTypeAggregation = avg(list) { it.exceptionTypeAggregation } } fun onDone(riskValue: RiskValue) { riskValue.type = "month" } private fun avg(list: List<RiskValue?>, onNext: (value: RiskValue) -> Double): Double { var total = .0 var count = 0 list.forEach { if (it == null) return@forEach total += onNext(it) count++ } return if (count == 0) .0 else total / count } } src/main/java/com/flightfeather/monitor/domain/ds1/repository/DustExceptionDataRep.kt
@@ -43,4 +43,14 @@ fun insert(list: List<DustExceptionData>): Int { return dustExceptionDataMapper.insertList(list) } fun select(mnCode: String, date: LocalDate): List<DustExceptionData?> { val s = date.atStartOfDay() val e = s.plusDays(1).minusSeconds(1) return dustExceptionDataMapper.selectByExample(Example(DustExceptionData::class.java).apply { createCriteria().andBetween("beginTime", s, e) .andEqualTo("mnCode", mnCode) orderBy("beginTime") }) } } src/main/java/com/flightfeather/monitor/domain/ds1/repository/DustStatisticsValueRep.kt
@@ -1,5 +1,6 @@ package com.flightfeather.monitor.domain.ds1.repository import com.flightfeather.monitor.domain.ds1.entity.DustExceptionData import com.flightfeather.monitor.domain.ds1.entity.DustStatisticsValue import com.flightfeather.monitor.domain.ds1.mapper.DustStatisticsValueMapper import com.github.pagehelper.PageHelper @@ -45,12 +46,17 @@ } fun monthlyStatics(date: LocalDate) { val s = date.atStartOfDay() val s = date.withDayOfMonth(1).atStartOfDay() val e = s.plusMonths(1).minusSeconds(1) val d = Duration.between(s, e).toDays() + 1 val dataCount = d * 96 dustStatisticsValueMapper.monthlyStatics(s, e, dataCount.toInt()) } fun select(mnCode: String, date: LocalDate): List<DustStatisticsValue?> { return dustStatisticsValueMapper.selectByExample(Example(DustStatisticsValue::class.java).apply { createCriteria().andEqualTo("lst", date) .andEqualTo("mnCode", mnCode) }) } } src/main/java/com/flightfeather/monitor/domain/ds1/repository/RiskValueRep.kt
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,41 @@ package com.flightfeather.monitor.domain.ds1.repository import com.flightfeather.monitor.domain.ds1.entity.RiskValue import com.flightfeather.monitor.domain.ds1.mapper.RiskValueMapper import com.github.pagehelper.PageHelper import org.springframework.stereotype.Repository import tk.mybatis.mapper.entity.Example import java.time.LocalDate @Repository class RiskValueRep(private val riskValueMapper: RiskValueMapper) { /** * è·åææ°ä¸æ¡è®°å½ */ fun findLatestData(type: String): RiskValue? { val p = PageHelper.startPage<RiskValue>(1, 1) riskValueMapper.selectByExample(Example(RiskValue::class.java).apply { createCriteria().andEqualTo("type", type) orderBy("lst").desc() }) return if (p.isNotEmpty()) { p[0] } else { null } } fun insert(list: List<RiskValue>): Int { return riskValueMapper.insertList(list) } fun select(mnCode: String, date: LocalDate): List<RiskValue?> { val s = date.withDayOfMonth(1).atStartOfDay() val e = s.plusMonths(1).minusSeconds(1) return riskValueMapper.selectByExample(Example(RiskValue::class.java).apply { createCriteria().andEqualTo("mnCode", mnCode) .andBetween("lst", s, e) }) } } src/test/java/com/flightfeather/monitor/analysis/dust/RiskAnalysisControllerTest.kt
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,35 @@ package com.flightfeather.monitor.analysis.dust import com.flightfeather.monitor.utils.DateUtil import org.junit.Test import org.junit.jupiter.api.extension.ExtendWith import org.junit.runner.RunWith import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.junit.jupiter.SpringExtension import org.springframework.test.context.junit4.SpringRunner import java.time.LocalDate @RunWith(SpringRunner::class) @ExtendWith(SpringExtension::class) @SpringBootTest class RiskAnalysisControllerTest { @Autowired lateinit var riskAnalysisController: RiskAnalysisController @Test fun autoRunDaily() { val s = LocalDate.of(2023, 10, 1) val e = LocalDate.of(2023, 10, 31) val du = DateUtil.findDurationDate(s, e) du.forEach { riskAnalysisController.runDaily(it) } } @Test fun autoRunMonthly() { riskAnalysisController.autoRunMonthly() } }