feiyu02
2024-01-26 01eae19a4870033e879a3faa6749eece92926cab
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
package com.flightfeather.uav.socket.processor
 
import com.flightfeather.uav.model.epw.EPWDataPrep
import com.flightfeather.uav.repository.AirDataRepository
import com.flightfeather.uav.socket.bean.AirDataPackage
import com.flightfeather.uav.socket.decoder.AirDataDecoder
import com.flightfeather.uav.socket.decoder.DataPackageDecoder
import com.flightfeather.uav.socket.eunm.AirCommandUnit
import com.flightfeather.uav.socket.eunm.UWDeviceType
import io.netty.channel.ChannelHandlerContext
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import java.text.SimpleDateFormat
import java.util.*
import javax.annotation.PostConstruct
 
/**
 * 处理socket接收的消息
 * Date: 2019.8.27
 * @author riku
 */
 
@Component
class UnderwayProcessor : BaseProcessor() {
 
    companion object {
        private lateinit var instance: UnderwayProcessor
 
        private const val TAG = "UAV"
    }
 
    @Autowired
    lateinit var airDataRepository: AirDataRepository
 
    private val airDataDecoder = AirDataDecoder.instance
    private val dataPackageDecoder = DataPackageDecoder()
 
    // 数据预处理函数
    private val dataProcessMap = mutableMapOf<String?, EPWDataPrep>()
 
    @PostConstruct
    fun init() {
        instance = this
    }
 
    override var tag: String = "走航监测"
 
    override fun dealStringMsg(msg: String, ctx: ChannelHandlerContext?) {
        //解包
        val packageData = airDataDecoder.decode(msg)
 
        if (bccCheck(msg)) {
            //保存
            deviceSession.saveDevice(packageData.deviceCode, ctx)
            saveToTxt(msg)
            saveToDataBase(packageData)
        } else {
            println("------${TAG}数据BCC校验失败,舍弃 [${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}]")
        }
    }
 
    /**
     * 保存至数据库
     */
    fun saveToDataBase(dataPackage: AirDataPackage) {
        when (dataPackage.commandUnit) {
            AirCommandUnit.AirData.value -> {
                // 以json格式存储原始数据
                instance.airDataRepository.saveAirData(dataPackage)
                // 进行预处理后,存储至对应数据表
                if (!dataProcessMap.containsKey(dataPackage.deviceCode)) {
                    dataProcessMap[dataPackage.deviceCode] = EPWDataPrep()// 每台设备有单独的数据预处理对象
                }
                dataProcessMap[dataPackage.deviceCode]?.run {
                    val list = this.mDataPrep2(dataPackage)// 数据平滑处理
                    instance.airDataRepository.savePrepData2(list)// 按照设备类型存储至对应数据表
                }
            }
        }
    }
 
    /**
     * BCC(异或校验)
     */
    fun bccCheck(msg: String): Boolean {
        val list = mutableListOf<String>().apply {
            addAll(dataPackageDecoder.toStringList(msg))
        }
        //取得数据包中的bcc校验结果
        val oldBcc = "${list[list.lastIndex - 1]}${list[list.lastIndex]}".toInt(16)
 
        //去除校验结果
        list.removeAt(list.lastIndex)
        list.removeAt(list.lastIndex)
 
        //计算bcc校验结果
        var newBcc = 0x00
        list.forEach {
            newBcc = newBcc.xor(it.toInt(16))
        }
 
        //返回校验结果是否正确
        return oldBcc == newBcc
    }
 
 
    fun encodeToBytes(msg: String): ByteArray {
        val list = msg.split(" ")
        val bytes = ByteArray(list.size)
        for (i in 0 until list.size) {
            bytes[i] = list[i].toInt(16).toByte()
        }
 
        return bytes
    }
 
    fun getDataPackage(deviceCode: String?): String? {
        if (deviceCode == null) return null
        //23 23 7f 31 37 36 39 31 35 33 31 39 30 39 31 32 30 30 31 31 01 01 00 00 39
        val sb = StringBuilder("23 23 10 ")
        deviceCode.forEach {
            sb.append(it.toInt().toString(16)).append(" ")
        }
        sb.append("01 01 00 00 00 0A 41 54 2B 56 45 52 53 49 4F 4E")
 
        val list = sb.split(" ")
 
        //计算bcc校验结果
        var bcc = 0x00
        list.forEach {
            bcc = bcc.xor(it.toInt(16))
        }
 
        sb.append(" ").append(bcc.toString(16))
 
        return sb.toString()
    }
}