feiyu02
2025-08-22 b315032d126a640758d4a6fccf297acbab057772
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
package com.flightfeather.uav.socket.decoder
 
import com.flightfeather.uav.socket.bean.DataUnit
import com.flightfeather.uav.socket.eunm.AirCommandUnit
import java.util.*
 
/**
 * uav 第一层数据包解码器
 * @author riku
 * Date: 2019/9/12
 *
 * 数据第一层结构定义如下:
 * 起始字节         定义
 * 0                    起始符
 * 1                   命令单元  类型@see [AirCommandUnit]
 * 2                   数据单元长度
 * 倒数第2           校验码
 */
class DataPackageDecoder {
 
    companion object {
        //        数据头
        const val HEAD_BYTES = 1
        //        监测参数确认指令位
        const val COMMAND_UNIT_BYTES = 1
        //        设备类型
        const val DEVICE_CODE_BYTES = 6
        //        本次监测的空气因子数量
        const val DATA_LENGTH = 1
        //        校验
        const val BCC_BYTES = 2
    }
 
    private val dataUnitDecoder: DataUnitDecoder = DataUnitDecoder()
 
 
    fun getHead(b: List<String>): String? {
        return if (b.isNotEmpty()) {
            val s = StringBuilder()
            repeat(HEAD_BYTES) {
                s.append(b[it])
            }
            s.toString()
        } else {
            null
        }
    }
 
    fun getCommandUnit(b: List<String>): Int? = if (b.size >= (HEAD_BYTES + COMMAND_UNIT_BYTES)) {
        val s = StringBuilder()
        repeat(COMMAND_UNIT_BYTES) {
            s.append(b[HEAD_BYTES + it])
        }
        s.toString().toIntOrNull(16)
    } else {
        null
    }
 
    fun getDeviceCode(b: List<String>): String? = if (b.size >= (HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES)) {
        //2021/1/7 '0A'代表车载设备,'0B'代表无人机设备,'0C'为网格化监测
        val s = StringBuilder()
        repeat(DEVICE_CODE_BYTES) {
            s.append(b[HEAD_BYTES + COMMAND_UNIT_BYTES + it])
        }
        s.toString()
    } else {
        null
    }
 
    fun getDataTime(b: List<String>): Date {
        // FIXME: 2021/1/7 采样时间和监测因子一同放在了数据部分,此处不再做解析
        return Date()
    }
 
    fun getDataLength(b: List<String>): Int {
        if (b.size <= HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES + DATA_LENGTH) return 0
 
        val hexNum = b[HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES]
 
        return hexNum.toIntOrNull(16) ?: 0
    }
 
    fun getDataUnit(b: List<String>): List<DataUnit> {
        if (getDataLength(b) == 0 || b.size <= HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES + DATA_LENGTH) {
            return emptyList()
        }
 
        val unit = mutableListOf<String>()
        val start = HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES + DATA_LENGTH
        for (i in start..b.size - 1 - BCC_BYTES) {
            unit.add(b[i])
        }
 
        dataUnitDecoder.run {
            return when (getCommandUnit(b)) {
                AirCommandUnit.Confirm.value -> getAirConfirmData(unit, getDeviceCode(b))
                AirCommandUnit.AirData.value -> getAirData(unit, getDeviceCode(b))
                else -> emptyList()
            }
        }
    }
 
    fun getCheckCode(b: List<String>): Int? {
        return if (b.size >= HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES + BCC_BYTES) {
            val hexNum = "${b[b.size - 2]}${b[b.size - 1]}"
 
            hexNum.toIntOrNull(16)
        } else {
            null
        }
    }
 
    fun toStringList(msg: String): List<String> {
        return msg.split(" ")
    }
 
 
}