riku
2019-09-23 14ce5d2ccfae554497763da846ffb9eb39cd6d34
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
package com.flightfeather.obd.socket.decoder.impl
 
import com.flightfeather.obd.socket.bean.*
import com.flightfeather.obd.socket.decoder.DataUnitDecoder
import com.flightfeather.obd.socket.decoder.RealTimeDataDecoder
import com.flightfeather.obd.socket.eunm.ObdDataType
import org.slf4j.LoggerFactory
import java.lang.StringBuilder
import java.util.*
 
/**
 * @author riku
 * Date: 2019/9/15
 */
class DataUnitDecoderImpl : DataUnitDecoder {
 
    private val logger = LoggerFactory.getLogger(javaClass.name)
    private var realTimeDataDecoder: RealTimeDataDecoder = RealTimeDataDecoderImpl()
 
    override fun getCarRegisterData(b: List<String>): List<CarRegisterData> {
        val time = decodeDataTime(b)
 
        val serialNum = "${b[6]}${b[7]}".toInt(16)
 
        val simCode = StringBuilder()
        for (i in 10 until b.size) {
            simCode.append(b[i].toInt(16).toChar())
        }
 
        return mutableListOf(CarRegisterData(time, serialNum, simCode.toString()))
    }
 
    override fun getRealTimeData(b: List<String>): List<RealTimeData> {
        val time = decodeDataTime(b)
 
        //国标法: 起始字节为7 开始的2个字节表示 流水号
//        val serialNum = "${b[7]}${b[8]}".toInt(16)
 
        //上海法: 起始字节为6 开始的2个字节表示 流水号
        val serialNum = "${b[6]}${b[7]}".toInt(16)
 
        val dataList = mutableListOf<String>().apply { addAll(b) }
        //删去前6位时间
        for (i in 0..5) {
            if (dataList.isNotEmpty()) dataList.removeAt(0)
        }
 
        //fixme 2019.9.15 目前两种规则有冲突,并且只从数据内容无法区分。暂时使用 国标法
        /*
        * 删去流水号,得到信息标志与信息体的组合
        * (国标法:去除前6位时间后,起始字节为1 开始的2个字节表示 流水号)
        */
//        if (dataList.size >= 2) dataList.removeAt(1)
//        if (dataList.size >= 2) dataList.removeAt(1)
 
        /*
        * 删去流水号,得到信息标志与信息体的组合
        * (上海法:去除前6位时间后,起始字节为0 开始的2个字节表示 流水号)
        */
        if (dataList.isNotEmpty()) dataList.removeAt(0)
        if (dataList.isNotEmpty()) dataList.removeAt(0)
 
        val resultList = mutableListOf<RealTimeData>()
 
        /*
         * 最终得到的数据结构为 [ 信息类型标志, 信息体, ...... , 信息类型标志, 信息体 ]
         */
        while (dataList.isNotEmpty()) {
            //得到最前面的一组信息类型+信息体列表
            val data = realTimeDataDecoder.getDataListByDataType(dataList)
            if (data.isNotEmpty()) {
                val r = when (data[0].toInt(16)) {
                    ObdDataType.ObdData.value -> realTimeDataDecoder.getObdData(time, serialNum, data)
                    ObdDataType.EngineDataFlow.value -> realTimeDataDecoder.getEngineDataStream(time, serialNum, data)
                    ObdDataType.SupplementDataFlow.value -> realTimeDataDecoder.getSupplementDataStream(time, serialNum, data)
                    else -> null
                }
 
                if (r != null) {
                    resultList.add(r)
                }
 
                for (i in 0 until data.size) {
                    if (dataList.isNotEmpty()) dataList.removeAt(0)
                }
            }else if (dataList.isNotEmpty()) {
                //按照规则没有取到信息体,并且原数据不为空,表示原数据格式错误,退出循环
                logger.error("-------数据信息流或补充数据流格式错误")
                break
            }
        }
 
        return resultList
    }
 
    override fun getReplacementData(b: List<String>): List<ReplacementData> = getRealTimeData(b)
 
    override fun getCarLogOutData(b: List<String>): List<CarLogOutData> {
        val time = decodeDataTime(b)
 
        val serialNum = "${b[6]}${b[7]}".toInt(16)
 
        return mutableListOf(CarLogOutData(time, serialNum))
    }
 
    override fun getTimeCalibrationData(b: List<String>): List<TimeCalibrationData> = emptyList()
 
    override fun decodeDataTime(b: List<String>): Date? {
        if (b.size < 6) {
            return null
        }
 
        val year = b[0].toInt(16) + 2000
        if (year < 2000 || year > 2099) return null
        val month = b[1].toInt(16)
        val day = b[2].toInt(16)
        val hour = b[3].toInt(16)
        val min = b[4].toInt(16)
        val sec = b[5].toInt(16)
        val cal  = Calendar.getInstance().apply {
            set(year, month - 1, day, hour, min, sec)
            set(Calendar.MILLISECOND, 0)
        }
 
        return cal.time
    }
}