feiyu02
2024-05-31 da431c25dfe5122e4ed70372da36ede3e4eaec4a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package com.flightfeather.uav.biz.dataprocess
 
import com.flightfeather.uav.common.utils.DateUtil
import com.flightfeather.uav.domain.entity.CompanyDevice
import com.flightfeather.uav.domain.entity.ElectricMinuteValue
import com.flightfeather.uav.lightshare.bean.ElectricDailyInfo
import java.time.LocalDateTime
import java.time.ZoneId
import kotlin.math.round
 
/**
 * 用电量日分析
 * Date 2021/12/1 14:53
 * Created by feiyu
 */
object ElectricDailyAnalysis {
 
    fun analysis(deviceList: List<CompanyDevice>, dataList: List<ElectricMinuteValue>): List<ElectricDailyInfo> {
        // 返回结果
        val result = mutableListOf<ElectricDailyInfo>()
        // 每日统计信息
        val dailyInfoMap = mutableMapOf<Int, ElectricDailyInfo>()
 
        // 1.数据准备
        val deviceMap = mutableMapOf<String, CompanyDevice>()
        val dataMap = mutableMapOf<String, MutableMap<Int, MutableList<ElectricMinuteValue>>>()
        deviceList.forEach {
            // 监测数据
            if (!dataMap.containsKey(it.cdDeviceCode)) {
                dataMap[it.cdDeviceCode] = mutableMapOf()
            }
            // 设备信息
            deviceMap[it.cdDeviceCode] = it
        }
        // 2.轮询数据,统计每日的各项特征
        dataList.forEach {
            // 获取日期
            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 = 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.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.6 统计各台设备分析结果
        dataMap.forEach { (dCode, dayMap) ->
            dayMap.forEach { (day, list) ->
                dailyInfoMap[day]?.apply {
                    changeType(deviceMap[dCode])
                    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)
    }
}