package cn.flightfeather.supervision.business.autooutput.dataanalysis
|
|
import cn.flightfeather.supervision.business.autooutput.AopOutput
|
import cn.flightfeather.supervision.business.autooutput.datasource.AopDataConfig
|
import cn.flightfeather.supervision.business.autooutput.datasource.AopDataSource
|
import cn.flightfeather.supervision.business.autooutput.datasource.AopDbMapper
|
import cn.flightfeather.supervision.business.autooutput.datasource.AopSceneTypeCheck
|
import cn.flightfeather.supervision.domain.ds1.entity.DustDataResult
|
import java.time.LocalDateTime
|
import java.time.ZoneId
|
import java.util.*
|
import kotlin.math.round
|
|
/**
|
* 监测数据分析入库
|
* 根据每月为一个周期,统计当月的超标次数、均值、最大最小值、超区均值百分比、数据个数、有效率等数据
|
*/
|
abstract class AopDataAnalysis<T>(
|
private val aopDbMapper: AopDbMapper,
|
private val aopSceneTypeCheck: AopSceneTypeCheck,
|
private val aopOutput: AopOutput,
|
) {
|
|
/**
|
* 统计数据 临时存储结构
|
*/
|
inner class TempResult(
|
var total: Double = .0,
|
var count: Int = 0,
|
){
|
var avg: Double = -1.0
|
get() {
|
if (field == -1.0) {
|
field = avg()
|
}
|
return field
|
}
|
|
private fun avg(): Double {
|
return if (count == 0) {
|
.0
|
} else {
|
round((total / count) * 1000) / 1000
|
}
|
}
|
}
|
|
//数据源
|
private var source: AopDataSource? = null
|
|
fun setResource(topTaskGuid: String?, sceneType: Int, year: Int, month: Int) {
|
source = AopDataSource(aopDbMapper, aopSceneTypeCheck)
|
val st = LocalDateTime.of(year, month, 1, 0, 0, 0)
|
val et = st.plusMonths(1).minusSeconds(1)
|
val sTime = Date.from(st.atZone(ZoneId.systemDefault()).toInstant())
|
val eTime = Date.from(et.atZone(ZoneId.systemDefault()).toInstant())
|
val config = AopDataConfig(topTaskGuid = topTaskGuid, sceneType = sceneType, startTime = sTime, endTime = eTime)
|
source?.setResource(config)
|
}
|
|
/**
|
* 执行统计逻辑
|
*/
|
fun execute(avg: Double? = null) {
|
//计算区均值
|
val dAvg = avg ?: districtAvg(source)
|
println("均值:${dAvg}")
|
//循环处理每个场景
|
source?.loop { _, evaluationScene ->
|
//获取原始监测数据
|
val dataList = fetchDataResources(evaluationScene)
|
//计算统计结果
|
var tempExceedTimes = TempResult()
|
var tempAvg = TempResult()
|
var tempMax = TempResult()
|
var tempMin = TempResult()
|
dataList.forEach {
|
// 监测点有多台设备时,每台设备单独统计,取均值最高的为统计结果
|
val _tempExceedTimes = TempResult()
|
val _tempAvg = TempResult()
|
val _tempMax = TempResult()
|
val _tempMin = TempResult()
|
it.forEach { t ->
|
t?.let {
|
exceedTimes(t, _tempExceedTimes)
|
avg(t, _tempAvg)
|
max(t, _tempMax)
|
min(t, _tempMin)
|
}
|
}
|
// 保留均值最高的一台设备
|
if (_tempAvg.avg > tempAvg.avg) {
|
tempExceedTimes = _tempExceedTimes
|
tempAvg = _tempAvg
|
tempMax = _tempMax
|
tempMin = _tempMin
|
}
|
}
|
val dustDataResult = DustDataResult().apply {
|
drSceneId = evaluationScene.scene.value?.guid
|
drSceneName = evaluationScene.scene.value?.name
|
drTime = source?.config?.startTime
|
drExceedTimes = tempExceedTimes.count
|
drAvg = tempAvg.avg
|
drMax = tempMax.total
|
drMin = tempMin.total
|
drOverAvgPer = overAvgRate(drAvg, dAvg)
|
drDataNum = count(dataList)
|
drEffectiveRate = effectiveRate(dataList, evaluationScene)
|
}
|
//更新入库
|
aopOutput.toDbDataResult(dustDataResult)
|
}
|
}
|
|
/**
|
* 计算区均值
|
* 当前为范围内全部监测点的均值
|
*/
|
abstract fun districtAvg(source: AopDataSource?): Double?
|
|
/**
|
* 获取原始监测数据
|
*/
|
abstract fun fetchDataResources(evaluationScene: AopDataSource.EvaluationScene): List<List<T?>>
|
|
/**
|
* 超标次数
|
*/
|
abstract fun exceedTimes(data: T, t: TempResult)
|
|
/**
|
* 月均值
|
*/
|
abstract fun avg(data: T, t: TempResult)
|
|
/**
|
* 最大值
|
*/
|
abstract fun max(data: T, t: TempResult)
|
|
/**
|
* 最小值
|
*/
|
abstract fun min(data: T, t: TempResult)
|
|
/**
|
* 超月均值百分比
|
*/
|
abstract fun overAvgRate(avg: Double, dAvg: Double?): Double?
|
|
/**
|
* 数据个数
|
*/
|
open fun count(dataList: List<List<T?>>): Int {
|
var count = 0
|
dataList.forEach {
|
count += it.size
|
}
|
return count
|
}
|
|
/**
|
* 有效率
|
*/
|
abstract fun effectiveRate(dataList: List<List<T?>>, evaluationScene: AopDataSource.EvaluationScene): Double
|
}
|