feiyu02
2021-12-30 88ae069fcf657c1790bb04b444e150c06f04e5f6
src/main/kotlin/com/flightfeather/uav/dataprocess/ElectricDailyAnalysis.kt
@@ -6,6 +6,7 @@
import com.flightfeather.uav.lightshare.bean.ElectricDailyInfo
import java.time.LocalDateTime
import java.time.ZoneId
import kotlin.math.round
/**
 * 用电量日分析
@@ -18,11 +19,11 @@
        // 返回结果
        val result = mutableListOf<ElectricDailyInfo>()
        // 每日统计信息
        val dailyInfoMap = mutableMapOf<String, ElectricDailyInfo>()
        val dailyInfoMap = mutableMapOf<Int, ElectricDailyInfo>()
        // 1.数据准备
        val deviceMap = mutableMapOf<String, CompanyDevice>()
        val dataMap = mutableMapOf<String, MutableMap<String, MutableList<ElectricMinuteValue>>>()
        val dataMap = mutableMapOf<String, MutableMap<Int, MutableList<ElectricMinuteValue>>>()
        deviceList.forEach {
            // 监测数据
            if (!dataMap.containsKey(it.cdDeviceCode)) {
@@ -34,36 +35,102 @@
        // 2.轮询数据,统计每日的各项特征
        dataList.forEach {
            // 获取日期
            val day = DateUtil.instance.dateToString(it.mvDataTime, DateUtil.DateStyle.YYYY_MM_DD) ?: ""
            val date = DateUtil.instance.dateToString(it.mvDataTime, DateUtil.DateStyle.YYYYMMDD) ?: ""
            val day = date.toIntOrNull() ?: 0
            // 每日对应一组数据
            if (dataMap[it.mvStatCode]?.containsKey(day) != true) dataMap[it.mvStatCode]?.put(day, mutableListOf())
            val dayList = dataMap[it.mvStatCode]?.get(day)!!
            dayList.add(it)
            // 数据对应状态
            val device = deviceMap[it.mvStatCode]
            val status = getStatus(it, device)
            // 2.1 根据数据切换当前设备类型
            if (!dailyInfoMap.containsKey(day)) dailyInfoMap[day] = ElectricDailyInfo()
            val dayResult = dailyInfoMap[day]!!
            dayResult.day = day
            dayResult.changeType(deviceMap[it.mvStatCode])
            dayResult.day = DateUtil.instance.dateToString(it.mvDataTime, DateUtil.DateStyle.YYYY_MM_DD) ?: ""
            dayResult.dayIndex = day
            dayResult.changeType(device)
            // 2.2 每日获取的首个数据,即为当日该设备开启时间
            if (dayList.size == 1) dayResult.setStartTime(it.mvDataTime)
            // 2.3 每个数据为分钟均值,总数代表开启时长
            dayResult.addRunTime(1)
            // 2.4 统计当日设备运行时段(小时)
            // 2.3 每日获取的首个为运行状态的数据,即为当日该设备正式运行开始时间
            dayResult.setRunningTime(status, it)
            // 2.4 每个数据为分钟均值,总数代表开启时长
            dayResult.addRunTime(status)
            // 2.5 统计当日设备运行时段(小时)
            val hour = LocalDateTime.ofInstant(it.mvDataTime.toInstant(), ZoneId.systemDefault()).hour
            dayResult.addRunPeriod(hour)
            // 2.6 累计用电量
            dayResult.addPower(it)
            // 2.7 设备首次从运行变为待机或关闭状态时,认为是设备的关闭时间
            dayResult.setEndTime(status, it)
        }
        // 2.5 统计各台设备每日结束时间及分析结果
        // 2.6 统计各台设备分析结果
        dataMap.forEach { (dCode, dayMap) ->
            dayMap.forEach { (day, list) ->
                dailyInfoMap[day]?.apply {
                    changeType(deviceMap[dCode])
                    setEndTime(list.last().mvDataTime)
                    setEndTime2(list.last().mvDataTime)
                    getResult()
                }
            }
        }
        dailyInfoMap.forEach { (_,v)-> result += v }
        result.sortBy { it.dayIndex }
        for (i in result.indices) {
            if (i > 0) {
                val last = result[i - 1]
                val d = result[i]
                // 针对两种设备,当昨天的设备未关闭,且今天的开启时间为0点0分内时,认为设备跨日运行
                if (last.plETimeStr == null && d.plRTimeStr?.substring(11, 16) == "00:00") {
                    d.plRTimeStr = null
                    d.rTimeDiff = null
                    d.sResult = true
                }
                if (last.pfETimeStr == null && d.pfRTimeStr?.substring(11, 16) == "00:00") {
                    d.pfRTimeStr = null
                    d.rTimeDiff = null
                    d.sResult = true
                }
            }
        }
        return result
    }
    /**
     * 获取设备当前运行状态
     * @param e 设备用电量监测数据
     * @param d 企业设备信息
     * @return 数据对应结果信息:<状态编号,状态描述,电流均值>
     */
    fun getStatus(e: ElectricMinuteValue?, d: CompanyDevice?): Triple<String, String, Double> {
        var values = mutableListOf<Int>().apply {
            d?.cdLimits?.split(";")?.forEach {
                it.toIntOrNull()?.let { i -> add(i) }
            }
        }
        var status = d?.cdStatus?.split(";") ?: emptyList()
        var statusNames = d?.cdStatusName?.split(";") ?: emptyList()
        if (values.isEmpty()) values = mutableListOf(1, 100)
        if (status.isEmpty()) status = listOf("0", "2", "3")
        if (statusNames.isEmpty()) statusNames = listOf("待机", "运行", "超负荷")
        if (e == null) {
            return Triple(status.first(), statusNames.first(), .0)
        }
        val electricityList = mutableListOf<Double>()
        electricityList.add(e.mvElectricityA)
        electricityList.add(e.mvElectricityB)
        electricityList.add(e.mvElectricityC)
        val avg = round(electricityList.average() * 100) / 100
        for (i in values.indices) {
            if (avg < values[i]) {
                return Triple(status[i], statusNames[i], avg)
            }
        }
        return Triple(status.last(), statusNames.last(), avg)
    }
}