riku
2019-09-15 4d44ed185203088052b10a8d1e3526fcbbc88331
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
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.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import java.lang.StringBuilder
import java.util.*
import javax.annotation.PostConstruct
 
/**
 * @author riku
 * Date: 2019/9/15
 */
class DataUnitDecoderImpl : DataUnitDecoder {
 
    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.getEngineDataFlow(time, serialNum, data)
                    ObdDataType.SupplementDataFlow.value -> realTimeDataDecoder.getSupplementDataFlow(time, serialNum, data)
                    else -> null
                }
 
                if (r != null) {
                    resultList.add(r)
                }
 
                for (i in 0 until data.size) {
                    if (dataList.isNotEmpty()) dataList.removeAt(0)
                }
            }
        }
 
        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)
        }
 
        return cal.time
    }
}