riku
2022-06-17 fd8c31dc5a0c0372d867335283f0b5272d667236
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package cn.flightfeather.supervision.timingtask
 
import cn.flightfeather.supervision.common.net.FumeHttpService
import cn.flightfeather.supervision.domain.entity.DeviceInfo
import cn.flightfeather.supervision.domain.entity.FumeMinuteValue
import cn.flightfeather.supervision.domain.enumeration.DistrictType
import cn.flightfeather.supervision.domain.enumeration.SceneType
import cn.flightfeather.supervision.domain.mapper.DeviceInfoMapper
import cn.flightfeather.supervision.domain.mapper.FumeMinuteValueMapper
import cn.flightfeather.supervision.infrastructure.utils.DateUtil
import com.github.pagehelper.PageHelper
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import tk.mybatis.mapper.entity.Example
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.ZoneId
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.util.*
import javax.annotation.PostConstruct
import kotlin.math.round
 
/**
 * 上传油烟监测数据
 */
@Component
class PushFume : BaseTimingTask() {
 
    companion object {
//        private lateinit var instance: PushFume
        val dateUtil = DateUtil()
        val LOGGER = LoggerFactory.getLogger(PushFume::class.java)
    }
 
    @Autowired
    lateinit var deviceInfoMapper: DeviceInfoMapper
 
    @Autowired
    lateinit var fumeMinuteValueMapper: FumeMinuteValueMapper
 
//    @PostConstruct
//    fun init() {
//        instance = this
//    }
 
    private val deviceCodeList = mutableListOf<String>()
 
    override val period: Long
        get() = 1L
 
    override fun doTask(localtime: LocalDateTime) {
        LOGGER.info("===========开始执行油烟数据上传任务===============")
        // 刷新监测点编号
        refreshDeviceCode()
 
        //每10分钟计算一次平均值并上传
        // FIXME: 2021/4/8 均值的计算逻辑之后应该放到其他模块
        val min = localtime.minute
        if (min != 0 && min != 10 && min != 20 && min != 30 && min != 40 && min != 50) return
 
        //计算取值时间
        val endTime = Date.from(localtime.minusMinutes(1).withSecond(59).atZone(ZoneId.systemDefault()).toInstant())
        val startTime = Date.from(localtime.minusMinutes(10).withSecond(0).atZone(ZoneId.systemDefault()).toInstant())
 
        //生成上传数据结构体
        val postData = FumeHttpService.PostData()
        val allData = mutableListOf<FumeMinuteValue>()
        deviceCodeList.forEach {
            //获取前10分钟的数据
            val dataList = fumeMinuteValueMapper.selectByExample(Example(FumeMinuteValue::class.java).apply {
                createCriteria().andEqualTo("mvStatCode", it)
                        .andBetween("mvCreateTime", startTime, endTime)
                and(createCriteria().orIsNull("mvUpload")
                        .orEqualTo("mvUpload", false))
            })
 
            //计算均值
            var count = 0
            var total = 0.0
            dataList.forEach {
                total += it.mvFumeConcentration2
                if (it.mvFumeConcentration2 != 0.0) {
                    count++
                }
            }
            if (count == 0) {
                dataUpdate(dataList)
                return@forEach
            }
            val average = round(total / count * 100) / 100
 
            //均值等于0,不上报,直接更新上传状态
            if (average == 0.0) {
                dataUpdate(dataList)
                return@forEach
            }
 
            //生成上传数据结构体
            dataList.last().let {
                postData.data.add(FumeHttpService.FumeData(
                        "hengzhiyuan_${it.mvStatCode}",
                        dateUtil.DateToString(startTime, DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS),
                        0.0, average,
                        if (it.mvFanStatus) 3 else 2,
                        it.mvFanElectricity, 0,
                        if (it.mvPurifierStatus) 3 else 2,
                        it.mvPurifierElectricity, 0,
                        0, 0.0
                ))
            }
 
            allData.addAll(dataList)
        }
 
        //上传数据并更新数据状态
        LOGGER.info("===========数据采样时间:$localtime")
        postData.data.forEach {
            LOGGER.info("${it.equipmentShowId}   **   ${it.dataTime}")
        }
        LOGGER.info("=================================")
        FumeHttpService.uploadData(postData)?.run {
            LOGGER.info(this.toString())
            if (this["code"].asInt == 0 && this["data"].asInt > 0) {
                dataUpdate(allData)
            }
            LOGGER.info("===========油烟数据上传任务结束============")
        }
    }
 
    /**
     * 刷新监测点编号
     */
    @Synchronized
    private fun refreshDeviceCode() {
        val now = LocalDateTime.now()
        if (deviceCodeList.isEmpty() || (now.hour == 0 && now.minute <= period)) {
            deviceCodeList.clear()
            deviceInfoMapper.selectByExample(Example(DeviceInfo::class.java).apply {
                createCriteria().andEqualTo("diProvinceCode", "31")
                        .andEqualTo("diCityCode", "3100")
                        .andEqualTo("diDistrictCode", DistrictType.XuHui.code)
                        .andEqualTo("diSceneTypeId", SceneType.Restaurant.value)
                        .andEqualTo("diDeviceTypeId", 1)
                        .andEqualTo("diSupplier", "hengzhiyuan")
            }).forEach {
                it?.let {
                    deviceCodeList.add(it.diCode)
                }
            }
        }
    }
 
    /**
     * 更新数据状态
     */
    private fun dataUpdate(dataList: List<FumeMinuteValue>) {
        dataList.forEach {
            it.mvUpload = true
            fumeMinuteValueMapper.updateByPrimaryKey(it)
        }
    }
}