From 9a5f9bfc4f4b153dd0175c63f563d8047e1e2515 Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期二, 02 六月 2020 16:43:57 +0800
Subject: [PATCH] 切换为无人机多参数接收服务端

---
 src/main/kotlin/com/flightfeather/uav/socket/eunm/ObdCommandUnit.kt                           |   27 
 src/main/kotlin/com/flightfeather/uav/domain/mapper/ObdInfoMapper.kt                          |    8 
 src/main/kotlin/com/flightfeather/uav/socket/bean/SupplementDataStream.kt                     |   59 
 src/main/kotlin/com/flightfeather/uav/repository/CarLogoutRepository.kt                       |   21 
 src/main/kotlin/com/flightfeather/uav/socket/bean/ObdInfo.kt                                  |   26 
 src/main/kotlin/com/flightfeather/uav/socket/ServerHandler.kt                                 |   70 
 src/main/kotlin/com/flightfeather/uav/lightshare/bean/CarLogoutVo.kt                          |   15 
 src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/VehicleServiceImpl.kt           |   28 
 src/main/kotlin/com/flightfeather/uav/socket/bean/ObdPackageData.kt                           |   40 
 src/main/kotlin/com/flightfeather/uav/socket/eunm/ObdDataType.kt                              |   20 
 src/main/kotlin/com/flightfeather/uav/repository/impl/ObdUserDaoImpl.kt                       |   34 
 src/main/kotlin/com/flightfeather/uav/common/Contanst.kt                                      |    9 
 src/main/kotlin/com/flightfeather/uav/lightshare/bean/ObdInfoVo.kt                            |   26 
 src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdDataService.kt                    |   60 
 src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdUserController.kt                     |   22 
 src/main/kotlin/com/flightfeather/uav/lightshare/bean/VehicleInfoVo.kt                        |   20 
 src/main/kotlin/com/flightfeather/uav/repository/ObdAlarmRepository.kt                        |   22 
 src/test/kotlin/com/flightfeather/uav/socket/MessageManagerTest.kt                            |   18 
 src/main/kotlin/com/flightfeather/uav/repository/OriginDataRepository.kt                      |   16 
 src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdUserService.kt                    |   13 
 src/main/kotlin/com/flightfeather/uav/domain/MyMapper.kt                                      |    8 
 src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdDataController.kt                     |   79 
 src/main/kotlin/com/flightfeather/uav/repository/impl/ObdAlarmDaoImpl.kt                      |   46 
 src/main/kotlin/com/flightfeather/uav/domain/mapper/ThresholdValueMapper.kt                   |    8 
 src/main/kotlin/com/flightfeather/uav/domain/entity/CarLogout.java                            |   92 
 src/main/kotlin/com/flightfeather/uav/domain/mapper/ObdUserMapper.kt                          |    8 
 src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdAlarmController.kt                    |   21 
 src/main/kotlin/com/flightfeather/uav/domain/entity/ObdUser.java                              |   91 
 src/main/kotlin/com/flightfeather/uav/domain/mapper/CarLogoutMapper.kt                        |    8 
 src/main/kotlin/com/flightfeather/uav/domain/mapper/OriginDataMapper.kt                       |    8 
 src/main/kotlin/com/flightfeather/uav/repository/impl/ObdDataDaoImpl.kt                       |  147 +
 src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdAlarmServiceImpl.kt          |   19 
 src/main/kotlin/com/flightfeather/uav/lightshare/service/VehicleService.kt                    |   17 
 src/main/kotlin/com/flightfeather/uav/socket/DeviceSession.kt                                 |   29 
 src/main/kotlin/com/flightfeather/uav/repository/VehicleRepository.kt                         |   15 
 src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdAlarmService.kt                   |   16 
 src/main/kotlin/com/flightfeather/uav/socket/bean/RealTimeData.kt                             |   26 
 src/main/kotlin/com/flightfeather/uav/repository/impl/VehicleRepositoryImpl.kt                |   24 
 src/main/kotlin/com/flightfeather/uav/repository/impl/OriginDataDaoImpl.kt                    |   29 
 src/main/kotlin/com/flightfeather/uav/repository/ObdDataRepository.kt                         |   25 
 src/main/kotlin/com/flightfeather/uav/common/utils/TimeUtil.kt                                |   31 
 src/main/kotlin/com/flightfeather/uav/lightshare/bean/DataStreamVo.kt                         |   42 
 src/main/kotlin/com/flightfeather/uav/lightshare/bean/ThresholdValueVo.kt                     |   37 
 src/main/kotlin/com/flightfeather/uav/socket/bean/ReplacementData.kt                          |   15 
 src/main/kotlin/com/flightfeather/uav/domain/entity/ObdInfo.java                              |  279 ++
 src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdDataServiceImpl.kt           |  164 +
 src/main/kotlin/com/flightfeather/uav/domain/entity/ThresholdValue.java                       |  499 ++++
 src/main/kotlin/com/flightfeather/uav/repository/DataStreamRepository.kt                      |   32 
 src/main/kotlin/com/flightfeather/uav/repository/ObdUserRepository.kt                         |   13 
 src/main/kotlin/com/flightfeather/uav/repository/impl/ObdInfoDaoImpl.kt                       |   68 
 src/test/kotlin/com/flightfeather/uav/socket/decoder/VehicleDataDecoderTest.kt                |  102 
 src/main/kotlin/com/flightfeather/uav/repository/CarLoginRepository.kt                        |   21 
 src/main/kotlin/com/flightfeather/uav/socket/MessageManager.kt                                |  205 +
 src/main/kotlin/com/flightfeather/uav/socket/bean/EngineDataStream.kt                         |   35 
 src/main/kotlin/com/flightfeather/uav/lightshare/bean/ObdDataVo.kt                            |   45 
 src/main/kotlin/com/flightfeather/uav/repository/ObdThresholdValueRepository.kt               |   27 
 src/main/kotlin/com/flightfeather/uav/repository/impl/DataStreamDaoImpl.kt                    |  157 +
 src/main/kotlin/com/flightfeather/uav/socket/ObdByteDataDecoder.kt                            |  112 
 src/main/kotlin/com/flightfeather/uav/common/utils/FileUtil.kt                                |  108 
 src/main/kotlin/com/flightfeather/uav/socket/decoder/DataUnitDecoder.kt                       |   36 
 src/main/kotlin/com/flightfeather/uav/domain/mapper/CarLoginMapper.kt                         |    8 
 src/main/kotlin/com/flightfeather/uav/domain/mapper/DataStreamMapper.kt                       |    8 
 src/main/kotlin/com/flightfeather/uav/socket/decoder/VehicleDataDecoder.kt                    |   32 
 src/main/kotlin/com/flightfeather/uav/domain/mapper/VehicleInfoMapper.kt                      |    8 
 src/test/kotlin/com/flightfeather/uav/Test.kt                                                 |  150 +
 src/main/kotlin/com/flightfeather/uav/domain/entity/VehicleInfo.java                          |   98 
 src/main/kotlin/com/flightfeather/uav/domain/entity/ObdData.java                              |  622 +++++
 src/main/kotlin/com/flightfeather/uav/socket/decoder/impl/RealTimeDataDecoderImpl.kt          |  185 +
 src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdUserServiceImpl.kt           |   18 
 src/main/kotlin/com/flightfeather/uav/lightshare/eunm/CarStatus.kt                            |   17 
 src/main/kotlin/com/flightfeather/uav/UAVApplication.kt                                       |   21 
 src/main/kotlin/com/flightfeather/uav/socket/bean/DataUnit.kt                                 |   16 
 src/main/kotlin/com/flightfeather/uav/domain/entity/CarLogin.java                             |  109 
 src/main/kotlin/com/flightfeather/uav/domain/entity/DataStream.java                           |  551 ++++
 src/main/kotlin/com/flightfeather/uav/lightshare/bean/CarLoginVo.kt                           |   16 
 src/main/kotlin/com/flightfeather/uav/domain/entity/AlarmData.java                            |  619 +++++
 src/main/kotlin/com/flightfeather/uav/lightshare/web/VehicleInfoController.kt                 |   22 
 src/main/kotlin/com/flightfeather/uav/lightshare/bean/AlarmDataVo.kt                          |   46 
 src/main/kotlin/com/flightfeather/uav/socket/decoder/DataPackageDecoder.kt                    |   42 
 src/main/kotlin/com/flightfeather/uav/repository/impl/CarLoginDaoImpl.kt                      |   68 
 src/main/kotlin/com/flightfeather/uav/socket/decoder/impl/DataUnitDecoderImpl.kt              |  127 +
 src/main/kotlin/com/flightfeather/uav/socket/bean/TimeCalibrationData.kt                      |   16 
 src/main/kotlin/com/flightfeather/uav/domain/mapper/AlarmDataMapper.kt                        |    8 
 src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdThresholdValueServiceImpl.kt |   27 
 src/main/kotlin/com/flightfeather/uav/lightshare/bean/LatLngVo.kt                             |   20 
 src/main/kotlin/com/flightfeather/uav/domain/entity/OriginData.java                           |  108 
 src/main/kotlin/com/flightfeather/uav/repository/impl/CarLogoutDaoImpl.kt                     |   65 
 src/main/kotlin/com/flightfeather/uav/ServletInitializer.kt                                   |   12 
 src/main/kotlin/com/flightfeather/uav/lightshare/eunm/CarType.kt                              |   12 
 src/main/kotlin/com/flightfeather/uav/socket/bean/CarRegisterData.kt                          |   22 
 src/main/kotlin/com/flightfeather/uav/socket/decoder/impl/DataPackageDecoderImpl.kt           |   98 
 src/main/kotlin/com/flightfeather/uav/socket/SocketServerClient.kt                            |   55 
 src/main/kotlin/com/flightfeather/uav/lightshare/bean/BaseJson.kt                             |   15 
 src/test/kotlin/com/flightfeather/uav/UAVApplicationTests.kt                                  |    9 
 src/main/kotlin/com/flightfeather/uav/domain/mapper/ObdDataMapper.kt                          |    8 
 src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdThresholdValueService.kt          |   26 
 src/main/kotlin/com/flightfeather/uav/repository/ObdInfoRepository.kt                         |   25 
 src/main/kotlin/com/flightfeather/uav/socket/bean/CarLogOutData.kt                            |   19 
 /dev/null                                                                                     |   23 
 src/main/kotlin/com/flightfeather/uav/repository/impl/ObdThresholdValueDaoImpl.kt             |   56 
 src/main/kotlin/com/flightfeather/uav/socket/decoder/RealTimeDataDecoder.kt                   |   26 
 src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdThresholdController.kt                |   32 
 src/main/kotlin/com/flightfeather/uav/lightshare/bean/ObdUserVo.kt                            |   13 
 103 files changed, 6,748 insertions(+), 28 deletions(-)

diff --git a/src/main/kotlin/com/flightfeather/obd/ObdApplication.kt b/src/main/kotlin/com/flightfeather/obd/ObdApplication.kt
deleted file mode 100644
index 362df64..0000000
--- a/src/main/kotlin/com/flightfeather/obd/ObdApplication.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.flightfeather.obd
-
-import com.flightfeather.obd.socket.SocketServerClient
-import org.springframework.boot.ApplicationRunner
-import org.springframework.boot.autoconfigure.EnableAutoConfiguration
-import org.springframework.boot.autoconfigure.SpringBootApplication
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
-import org.springframework.boot.runApplication
-import org.springframework.context.annotation.Bean
-
-@SpringBootApplication
-class ObdApplication{
-
-    @Bean
-    fun runner() = ApplicationRunner{
-        SocketServerClient().startServer(9000)
-    }
-}
-
-fun main(args: Array<String>) {
-
-    runApplication<ObdApplication>(*args)
-}
diff --git a/src/main/kotlin/com/flightfeather/uav/ServletInitializer.kt b/src/main/kotlin/com/flightfeather/uav/ServletInitializer.kt
new file mode 100644
index 0000000..4c71a55
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/ServletInitializer.kt
@@ -0,0 +1,12 @@
+package com.flightfeather.uav
+
+import org.springframework.boot.builder.SpringApplicationBuilder
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer
+
+class ServletInitializer : SpringBootServletInitializer() {
+
+    override fun configure(application: SpringApplicationBuilder): SpringApplicationBuilder {
+        return application.sources(UAVApplication::class.java)
+    }
+
+}
diff --git a/src/main/kotlin/com/flightfeather/uav/UAVApplication.kt b/src/main/kotlin/com/flightfeather/uav/UAVApplication.kt
new file mode 100644
index 0000000..46b8e1d
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/UAVApplication.kt
@@ -0,0 +1,21 @@
+package com.flightfeather.uav
+
+import com.flightfeather.uav.socket.SocketServerClient
+import org.springframework.boot.ApplicationRunner
+import org.springframework.boot.autoconfigure.SpringBootApplication
+import org.springframework.boot.runApplication
+import org.springframework.context.annotation.Bean
+
+@SpringBootApplication
+class UAVApplication{
+
+    @Bean
+    fun runner() = ApplicationRunner{
+        SocketServerClient().startServer(9000)
+    }
+}
+
+fun main(args: Array<String>) {
+
+    runApplication<UAVApplication>(*args)
+}
diff --git a/src/main/kotlin/com/flightfeather/uav/common/Contanst.kt b/src/main/kotlin/com/flightfeather/uav/common/Contanst.kt
new file mode 100644
index 0000000..6321329
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/common/Contanst.kt
@@ -0,0 +1,9 @@
+package com.flightfeather.uav.common
+
+/**
+ * @author riku
+ * Date: 2019/9/20
+ */
+//鍓嶇璁惧浼犺緭鐨勬棤鏁堝��
+const val INVALID_DATA_4_BYTE = "FFFFFFFF"
+const val INVALID_DATA_2_BYTE = "FFFF"
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/common/utils/FileUtil.kt b/src/main/kotlin/com/flightfeather/uav/common/utils/FileUtil.kt
new file mode 100644
index 0000000..f290f76
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/common/utils/FileUtil.kt
@@ -0,0 +1,108 @@
+package com.flightfeather.uav.common.utils
+
+import java.io.BufferedWriter
+import java.io.File
+import java.io.FileWriter
+import java.text.SimpleDateFormat
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/11
+ */
+class FileUtil {
+
+    private var file: File
+    private var basePath:String = "${File.separator}ObdData${File.separator}"
+    private var closeThread: Thread? = null
+    private var fw: FileWriter? = null
+    private var bw: BufferedWriter? = null
+    private var oldTime: Date
+
+    init {
+        val fileName = "data-${SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(Date())}.txt"
+        val path = "$basePath$fileName"
+        file = File(path)
+        oldTime = Date()
+    }
+
+    companion object{
+        var instance: FileUtil? = null
+        get() {
+            if (field == null) {
+                field = FileUtil()
+            }
+            return field
+        }
+    }
+
+    fun saveObdData(str: String) {
+        //妫�鏌ユ枃妗f槸鍚﹀瓨鍦�
+        if (!file.exists()) {
+            file.parentFile.mkdirs()
+            println("----鍒涘缓鏂囦欢澶癸細${file.parentFile.absolutePath}")
+            file.createNewFile()
+            println("----鍒涘缓鏂囦欢锛�${file.absolutePath}")
+        }
+        //鏂囦欢鏈�澶�512Kb,瓒呰繃鍚庢柊寤烘枃妗�
+        if (file.length() + str.toByteArray().size > 512 * 1024 || TimeUtil.isNextDay(oldTime, Date())) {
+            //瓒呰繃涓�澶╁悗锛屾洿鏂板綋鍓嶆椂闂�
+            oldTime = Date()
+
+            val fileName = "data-${SimpleDateFormat("yyyy-MM-dd-hh-mm-ss").format(Date())}.txt"
+            val path = "$basePath$fileName"
+            file = File(path)
+            file.createNewFile()
+
+            //鍏抽棴鍘熸湁杈撳嚭娴�
+            bw?.run {
+                flush()
+                close()
+            }
+            fw?.run {
+                flush()
+                close()
+            }
+            //鏂板缓杈撳嚭娴�
+            fw = FileWriter(file, true)
+            bw = BufferedWriter(fw)
+        }
+        //绗竴娆″啓鏂囨。鏃跺垵濮嬪寲杈撳嚭娴�
+        if (bw == null || fw == null) {
+            fw = FileWriter(file, true)
+            bw = BufferedWriter(fw)
+        }
+
+        bw?.run {
+            write(str)
+            newLine()
+            flush()
+        }
+
+        readyToShutDownStream(bw, fw)
+        println("----鍐欏叆瀹屾垚")
+
+    }
+
+    private fun readyToShutDownStream(bw: BufferedWriter?, fw:FileWriter?) {
+        //缁堢涓婁竴娆$殑璁℃椂绾跨▼
+        closeThread?.interrupt()
+        closeThread = Thread(Runnable {
+            //2鍒嗛挓娌℃湁鏂扮殑鏁版嵁鍐欏叆灏卞叧闂緭鍑烘祦
+            try {
+                Thread.sleep(20 * 1000)
+            } catch (e: Throwable) {
+            }
+            bw?.run {
+                close()
+            }
+            this.bw = null
+            fw?.run {
+                close()
+            }
+            this.fw = null
+        }).also {
+            it.start()
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/common/utils/TimeUtil.kt b/src/main/kotlin/com/flightfeather/uav/common/utils/TimeUtil.kt
new file mode 100644
index 0000000..246b159
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/common/utils/TimeUtil.kt
@@ -0,0 +1,31 @@
+package com.flightfeather.uav.common.utils
+
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/16
+ */
+class TimeUtil {
+
+    companion object {
+        /**
+         * 鏄惁鏄浜屽ぉ鎴栨洿鏂扮殑鏃堕棿
+         */
+        fun isNextDay(oldTime: Date, newTime: Date): Boolean {
+            val oldC = Calendar.getInstance().apply {
+                time = oldTime
+            }
+            val newC = Calendar.getInstance().apply {
+                time = newTime
+            }
+
+            return when {
+                newC[Calendar.YEAR] > oldC[Calendar.YEAR] -> true
+                newC[Calendar.YEAR] == oldC[Calendar.YEAR] -> newC[Calendar.DAY_OF_YEAR] > oldC[Calendar.DAY_OF_YEAR]
+                else -> false
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/MyMapper.kt b/src/main/kotlin/com/flightfeather/uav/domain/MyMapper.kt
new file mode 100644
index 0000000..be0379d
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/MyMapper.kt
@@ -0,0 +1,8 @@
+package com.flightfeather.uav.domain
+
+import tk.mybatis.mapper.common.Mapper
+import tk.mybatis.mapper.common.MySqlMapper
+
+interface MyMapper<T> : Mapper<T>, MySqlMapper<T> {
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/AlarmData.java b/src/main/kotlin/com/flightfeather/uav/domain/entity/AlarmData.java
new file mode 100644
index 0000000..0329f4a
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/entity/AlarmData.java
@@ -0,0 +1,619 @@
+package com.flightfeather.uav.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "obd_alarm_data")
+public class AlarmData {
+    @Id
+    private Integer id;
+
+    @Column(name = "obd_vin")
+    private String obdVin;
+
+    @Column(name = "alarm_time")
+    private Date alarmTime;
+
+    @Column(name = "alarm_lng")
+    private Double alarmLng;
+
+    @Column(name = "alarm_lat")
+    private Double alarmLat;
+
+    @Column(name = "alarm_protocol")
+    private Integer alarmProtocol;
+
+    @Column(name = "alarm_mil")
+    private Integer alarmMil;
+
+    @Column(name = "alarm_id_code")
+    private String alarmIdCode;
+
+    @Column(name = "alarm_verification_code")
+    private String alarmVerificationCode;
+
+    @Column(name = "alarm_fault_code_num")
+    private Integer alarmFaultCodeNum;
+
+    @Column(name = "alarm_fault_code")
+    private String alarmFaultCode;
+
+    @Column(name = "alarm_speed")
+    private Integer alarmSpeed;
+
+    @Column(name = "alarm_air_pressure")
+    private Double alarmAirPressure;
+
+    @Column(name = "alarm_engine_torque")
+    private Double alarmEngineTorque;
+
+    @Column(name = "alarm_friction_torque")
+    private Double alarmFrictionTorque;
+
+    @Column(name = "alarm_engine_rpm")
+    private Integer alarmEngineRpm;
+
+    @Column(name = "alarm_start_fuel_flow")
+    private Double alarmStartFuelFlow;
+
+    @Column(name = "alarm_scr_upstream_NO")
+    private Double alarmScrUpstreamNo;
+
+    @Column(name = "alarm_scr_downstream_NO")
+    private Double alarmScrDownstreamNo;
+
+    @Column(name = "alarm_remain_reactant")
+    private Double alarmRemainReactant;
+
+    @Column(name = "alarm_air_input")
+    private Double alarmAirInput;
+
+    @Column(name = "alarm_scr_input_temp")
+    private Double alarmScrInputTemp;
+
+    @Column(name = "alarm_scr_output_temp")
+    private Double alarmScrOutputTemp;
+
+    @Column(name = "alarm_DPF")
+    private Double alarmDpf;
+
+    @Column(name = "alarm_engine_coolant_temp")
+    private Double alarmEngineCoolantTemp;
+
+    @Column(name = "alarm_fuel_level")
+    private Double alarmFuelLevel;
+
+    @Column(name = "alarm_location_status")
+    private Integer alarmLocationStatus;
+
+    @Column(name = "alarm_total_mileage")
+    private Double alarmTotalMileage;
+
+    @Column(name = "alarm_engine_torque_mode")
+    private String alarmEngineTorqueMode;
+
+    @Column(name = "alarm_accelerator_pedal")
+    private Double alarmAcceleratorPedal;
+
+    @Column(name = "alarm_total_oil_consumption")
+    private Double alarmTotalOilConsumption;
+
+    @Column(name = "alarm_urea_box_temp")
+    private Double alarmUreaBoxTemp;
+
+    @Column(name = "alarm_urea_volume")
+    private Integer alarmUreaVolume;
+
+    @Column(name = "alarm_total_urea_consume")
+    private Double alarmTotalUreaConsume;
+
+    @Column(name = "alarm_DPF_temp")
+    private Double alarmDpfTemp;
+
+    @Column(name = "alarm_firmware_version")
+    private String alarmFirmwareVersion;
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * @return obd_vin
+     */
+    public String getObdVin() {
+        return obdVin;
+    }
+
+    /**
+     * @param obdVin
+     */
+    public void setObdVin(String obdVin) {
+        this.obdVin = obdVin == null ? null : obdVin.trim();
+    }
+
+    /**
+     * @return alarm_time
+     */
+    public Date getAlarmTime() {
+        return alarmTime;
+    }
+
+    /**
+     * @param alarmTime
+     */
+    public void setAlarmTime(Date alarmTime) {
+        this.alarmTime = alarmTime;
+    }
+
+    /**
+     * @return alarm_lng
+     */
+    public Double getAlarmLng() {
+        return alarmLng;
+    }
+
+    /**
+     * @param alarmLng
+     */
+    public void setAlarmLng(Double alarmLng) {
+        this.alarmLng = alarmLng;
+    }
+
+    /**
+     * @return alarm_lat
+     */
+    public Double getAlarmLat() {
+        return alarmLat;
+    }
+
+    /**
+     * @param alarmLat
+     */
+    public void setAlarmLat(Double alarmLat) {
+        this.alarmLat = alarmLat;
+    }
+
+    /**
+     * @return alarm_protocol
+     */
+    public Integer getAlarmProtocol() {
+        return alarmProtocol;
+    }
+
+    /**
+     * @param alarmProtocol
+     */
+    public void setAlarmProtocol(Integer alarmProtocol) {
+        this.alarmProtocol = alarmProtocol;
+    }
+
+    /**
+     * @return alarm_mil
+     */
+    public Integer getAlarmMil() {
+        return alarmMil;
+    }
+
+    /**
+     * @param alarmMil
+     */
+    public void setAlarmMil(Integer alarmMil) {
+        this.alarmMil = alarmMil;
+    }
+
+    /**
+     * @return alarm_id_code
+     */
+    public String getAlarmIdCode() {
+        return alarmIdCode;
+    }
+
+    /**
+     * @param alarmIdCode
+     */
+    public void setAlarmIdCode(String alarmIdCode) {
+        this.alarmIdCode = alarmIdCode == null ? null : alarmIdCode.trim();
+    }
+
+    /**
+     * @return alarm_verification_code
+     */
+    public String getAlarmVerificationCode() {
+        return alarmVerificationCode;
+    }
+
+    /**
+     * @param alarmVerificationCode
+     */
+    public void setAlarmVerificationCode(String alarmVerificationCode) {
+        this.alarmVerificationCode = alarmVerificationCode == null ? null : alarmVerificationCode.trim();
+    }
+
+    /**
+     * @return alarm_fault_code_num
+     */
+    public Integer getAlarmFaultCodeNum() {
+        return alarmFaultCodeNum;
+    }
+
+    /**
+     * @param alarmFaultCodeNum
+     */
+    public void setAlarmFaultCodeNum(Integer alarmFaultCodeNum) {
+        this.alarmFaultCodeNum = alarmFaultCodeNum;
+    }
+
+    /**
+     * @return alarm_fault_code
+     */
+    public String getAlarmFaultCode() {
+        return alarmFaultCode;
+    }
+
+    /**
+     * @param alarmFaultCode
+     */
+    public void setAlarmFaultCode(String alarmFaultCode) {
+        this.alarmFaultCode = alarmFaultCode == null ? null : alarmFaultCode.trim();
+    }
+
+    /**
+     * @return alarm_speed
+     */
+    public Integer getAlarmSpeed() {
+        return alarmSpeed;
+    }
+
+    /**
+     * @param alarmSpeed
+     */
+    public void setAlarmSpeed(Integer alarmSpeed) {
+        this.alarmSpeed = alarmSpeed;
+    }
+
+    /**
+     * @return alarm_air_pressure
+     */
+    public Double getAlarmAirPressure() {
+        return alarmAirPressure;
+    }
+
+    /**
+     * @param alarmAirPressure
+     */
+    public void setAlarmAirPressure(Double alarmAirPressure) {
+        this.alarmAirPressure = alarmAirPressure;
+    }
+
+    /**
+     * @return alarm_engine_torque
+     */
+    public Double getAlarmEngineTorque() {
+        return alarmEngineTorque;
+    }
+
+    /**
+     * @param alarmEngineTorque
+     */
+    public void setAlarmEngineTorque(Double alarmEngineTorque) {
+        this.alarmEngineTorque = alarmEngineTorque;
+    }
+
+    /**
+     * @return alarm_friction_torque
+     */
+    public Double getAlarmFrictionTorque() {
+        return alarmFrictionTorque;
+    }
+
+    /**
+     * @param alarmFrictionTorque
+     */
+    public void setAlarmFrictionTorque(Double alarmFrictionTorque) {
+        this.alarmFrictionTorque = alarmFrictionTorque;
+    }
+
+    /**
+     * @return alarm_engine_rpm
+     */
+    public Integer getAlarmEngineRpm() {
+        return alarmEngineRpm;
+    }
+
+    /**
+     * @param alarmEngineRpm
+     */
+    public void setAlarmEngineRpm(Integer alarmEngineRpm) {
+        this.alarmEngineRpm = alarmEngineRpm;
+    }
+
+    /**
+     * @return alarm_start_fuel_flow
+     */
+    public Double getAlarmStartFuelFlow() {
+        return alarmStartFuelFlow;
+    }
+
+    /**
+     * @param alarmStartFuelFlow
+     */
+    public void setAlarmStartFuelFlow(Double alarmStartFuelFlow) {
+        this.alarmStartFuelFlow = alarmStartFuelFlow;
+    }
+
+    /**
+     * @return alarm_scr_upstream_NO
+     */
+    public Double getAlarmScrUpstreamNo() {
+        return alarmScrUpstreamNo;
+    }
+
+    /**
+     * @param alarmScrUpstreamNo
+     */
+    public void setAlarmScrUpstreamNo(Double alarmScrUpstreamNo) {
+        this.alarmScrUpstreamNo = alarmScrUpstreamNo;
+    }
+
+    /**
+     * @return alarm_scr_downstream_NO
+     */
+    public Double getAlarmScrDownstreamNo() {
+        return alarmScrDownstreamNo;
+    }
+
+    /**
+     * @param alarmScrDownstreamNo
+     */
+    public void setAlarmScrDownstreamNo(Double alarmScrDownstreamNo) {
+        this.alarmScrDownstreamNo = alarmScrDownstreamNo;
+    }
+
+    /**
+     * @return alarm_remain_reactant
+     */
+    public Double getAlarmRemainReactant() {
+        return alarmRemainReactant;
+    }
+
+    /**
+     * @param alarmRemainReactant
+     */
+    public void setAlarmRemainReactant(Double alarmRemainReactant) {
+        this.alarmRemainReactant = alarmRemainReactant;
+    }
+
+    /**
+     * @return alarm_air_input
+     */
+    public Double getAlarmAirInput() {
+        return alarmAirInput;
+    }
+
+    /**
+     * @param alarmAirInput
+     */
+    public void setAlarmAirInput(Double alarmAirInput) {
+        this.alarmAirInput = alarmAirInput;
+    }
+
+    /**
+     * @return alarm_scr_input_temp
+     */
+    public Double getAlarmScrInputTemp() {
+        return alarmScrInputTemp;
+    }
+
+    /**
+     * @param alarmScrInputTemp
+     */
+    public void setAlarmScrInputTemp(Double alarmScrInputTemp) {
+        this.alarmScrInputTemp = alarmScrInputTemp;
+    }
+
+    /**
+     * @return alarm_scr_output_temp
+     */
+    public Double getAlarmScrOutputTemp() {
+        return alarmScrOutputTemp;
+    }
+
+    /**
+     * @param alarmScrOutputTemp
+     */
+    public void setAlarmScrOutputTemp(Double alarmScrOutputTemp) {
+        this.alarmScrOutputTemp = alarmScrOutputTemp;
+    }
+
+    /**
+     * @return alarm_DPF
+     */
+    public Double getAlarmDpf() {
+        return alarmDpf;
+    }
+
+    /**
+     * @param alarmDpf
+     */
+    public void setAlarmDpf(Double alarmDpf) {
+        this.alarmDpf = alarmDpf;
+    }
+
+    /**
+     * @return alarm_engine_coolant_temp
+     */
+    public Double getAlarmEngineCoolantTemp() {
+        return alarmEngineCoolantTemp;
+    }
+
+    /**
+     * @param alarmEngineCoolantTemp
+     */
+    public void setAlarmEngineCoolantTemp(Double alarmEngineCoolantTemp) {
+        this.alarmEngineCoolantTemp = alarmEngineCoolantTemp;
+    }
+
+    /**
+     * @return alarm_fuel_level
+     */
+    public Double getAlarmFuelLevel() {
+        return alarmFuelLevel;
+    }
+
+    /**
+     * @param alarmFuelLevel
+     */
+    public void setAlarmFuelLevel(Double alarmFuelLevel) {
+        this.alarmFuelLevel = alarmFuelLevel;
+    }
+
+    /**
+     * @return alarm_location_status
+     */
+    public Integer getAlarmLocationStatus() {
+        return alarmLocationStatus;
+    }
+
+    /**
+     * @param alarmLocationStatus
+     */
+    public void setAlarmLocationStatus(Integer alarmLocationStatus) {
+        this.alarmLocationStatus = alarmLocationStatus;
+    }
+
+    /**
+     * @return alarm_total_mileage
+     */
+    public Double getAlarmTotalMileage() {
+        return alarmTotalMileage;
+    }
+
+    /**
+     * @param alarmTotalMileage
+     */
+    public void setAlarmTotalMileage(Double alarmTotalMileage) {
+        this.alarmTotalMileage = alarmTotalMileage;
+    }
+
+    /**
+     * @return alarm_engine_torque_mode
+     */
+    public String getAlarmEngineTorqueMode() {
+        return alarmEngineTorqueMode;
+    }
+
+    /**
+     * @param alarmEngineTorqueMode
+     */
+    public void setAlarmEngineTorqueMode(String alarmEngineTorqueMode) {
+        this.alarmEngineTorqueMode = alarmEngineTorqueMode == null ? null : alarmEngineTorqueMode.trim();
+    }
+
+    /**
+     * @return alarm_accelerator_pedal
+     */
+    public Double getAlarmAcceleratorPedal() {
+        return alarmAcceleratorPedal;
+    }
+
+    /**
+     * @param alarmAcceleratorPedal
+     */
+    public void setAlarmAcceleratorPedal(Double alarmAcceleratorPedal) {
+        this.alarmAcceleratorPedal = alarmAcceleratorPedal;
+    }
+
+    /**
+     * @return alarm_total_oil_consumption
+     */
+    public Double getAlarmTotalOilConsumption() {
+        return alarmTotalOilConsumption;
+    }
+
+    /**
+     * @param alarmTotalOilConsumption
+     */
+    public void setAlarmTotalOilConsumption(Double alarmTotalOilConsumption) {
+        this.alarmTotalOilConsumption = alarmTotalOilConsumption;
+    }
+
+    /**
+     * @return alarm_urea_box_temp
+     */
+    public Double getAlarmUreaBoxTemp() {
+        return alarmUreaBoxTemp;
+    }
+
+    /**
+     * @param alarmUreaBoxTemp
+     */
+    public void setAlarmUreaBoxTemp(Double alarmUreaBoxTemp) {
+        this.alarmUreaBoxTemp = alarmUreaBoxTemp;
+    }
+
+    /**
+     * @return alarm_urea_volume
+     */
+    public Integer getAlarmUreaVolume() {
+        return alarmUreaVolume;
+    }
+
+    /**
+     * @param alarmUreaVolume
+     */
+    public void setAlarmUreaVolume(Integer alarmUreaVolume) {
+        this.alarmUreaVolume = alarmUreaVolume;
+    }
+
+    /**
+     * @return alarm_total_urea_consume
+     */
+    public Double getAlarmTotalUreaConsume() {
+        return alarmTotalUreaConsume;
+    }
+
+    /**
+     * @param alarmTotalUreaConsume
+     */
+    public void setAlarmTotalUreaConsume(Double alarmTotalUreaConsume) {
+        this.alarmTotalUreaConsume = alarmTotalUreaConsume;
+    }
+
+    /**
+     * @return alarm_DPF_temp
+     */
+    public Double getAlarmDpfTemp() {
+        return alarmDpfTemp;
+    }
+
+    /**
+     * @param alarmDpfTemp
+     */
+    public void setAlarmDpfTemp(Double alarmDpfTemp) {
+        this.alarmDpfTemp = alarmDpfTemp;
+    }
+
+    /**
+     * @return alarm_firmware_version
+     */
+    public String getAlarmFirmwareVersion() {
+        return alarmFirmwareVersion;
+    }
+
+    /**
+     * @param alarmFirmwareVersion
+     */
+    public void setAlarmFirmwareVersion(String alarmFirmwareVersion) {
+        this.alarmFirmwareVersion = alarmFirmwareVersion == null ? null : alarmFirmwareVersion.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/CarLogin.java b/src/main/kotlin/com/flightfeather/uav/domain/entity/CarLogin.java
new file mode 100644
index 0000000..583af4a
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/entity/CarLogin.java
@@ -0,0 +1,109 @@
+package com.flightfeather.uav.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "obd_car_login")
+public class CarLogin {
+    @Id
+    private Integer id;
+
+    @Column(name = "obd_device_code")
+    private String obdDeviceCode;
+
+    @Column(name = "login_create_time")
+    private Date loginCreateTime;
+
+    @Column(name = "login_data_time")
+    private Date loginDataTime;
+
+    @Column(name = "login_serial_num")
+    private Integer loginSerialNum;
+
+    @Column(name = "login_sim_code")
+    private String loginSimCode;
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * @return obd_device_code
+     */
+    public String getObdDeviceCode() {
+        return obdDeviceCode;
+    }
+
+    /**
+     * @param obdDeviceCode
+     */
+    public void setObdDeviceCode(String obdDeviceCode) {
+        this.obdDeviceCode = obdDeviceCode == null ? null : obdDeviceCode.trim();
+    }
+
+    /**
+     * @return login_create_time
+     */
+    public Date getLoginCreateTime() {
+        return loginCreateTime;
+    }
+
+    /**
+     * @param loginCreateTime
+     */
+    public void setLoginCreateTime(Date loginCreateTime) {
+        this.loginCreateTime = loginCreateTime;
+    }
+
+    /**
+     * @return login_data_time
+     */
+    public Date getLoginDataTime() {
+        return loginDataTime;
+    }
+
+    /**
+     * @param loginDataTime
+     */
+    public void setLoginDataTime(Date loginDataTime) {
+        this.loginDataTime = loginDataTime;
+    }
+
+    /**
+     * @return login_serial_num
+     */
+    public Integer getLoginSerialNum() {
+        return loginSerialNum;
+    }
+
+    /**
+     * @param loginSerialNum
+     */
+    public void setLoginSerialNum(Integer loginSerialNum) {
+        this.loginSerialNum = loginSerialNum;
+    }
+
+    /**
+     * @return login_sim_code
+     */
+    public String getLoginSimCode() {
+        return loginSimCode;
+    }
+
+    /**
+     * @param loginSimCode
+     */
+    public void setLoginSimCode(String loginSimCode) {
+        this.loginSimCode = loginSimCode == null ? null : loginSimCode.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/CarLogout.java b/src/main/kotlin/com/flightfeather/uav/domain/entity/CarLogout.java
new file mode 100644
index 0000000..3c17d70
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/entity/CarLogout.java
@@ -0,0 +1,92 @@
+package com.flightfeather.uav.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "obd_car_logout")
+public class CarLogout {
+    @Id
+    private Integer id;
+
+    @Column(name = "obd_device_code")
+    private String obdDeviceCode;
+
+    @Column(name = "logout_create_time")
+    private Date logoutCreateTime;
+
+    @Column(name = "logout_data_time")
+    private Date logoutDataTime;
+
+    @Column(name = "logout_serial_num")
+    private Integer logoutSerialNum;
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * @return obd_device_code
+     */
+    public String getObdDeviceCode() {
+        return obdDeviceCode;
+    }
+
+    /**
+     * @param obdDeviceCode
+     */
+    public void setObdDeviceCode(String obdDeviceCode) {
+        this.obdDeviceCode = obdDeviceCode == null ? null : obdDeviceCode.trim();
+    }
+
+    /**
+     * @return logout_create_time
+     */
+    public Date getLogoutCreateTime() {
+        return logoutCreateTime;
+    }
+
+    /**
+     * @param logoutCreateTime
+     */
+    public void setLogoutCreateTime(Date logoutCreateTime) {
+        this.logoutCreateTime = logoutCreateTime;
+    }
+
+    /**
+     * @return logout_data_time
+     */
+    public Date getLogoutDataTime() {
+        return logoutDataTime;
+    }
+
+    /**
+     * @param logoutDataTime
+     */
+    public void setLogoutDataTime(Date logoutDataTime) {
+        this.logoutDataTime = logoutDataTime;
+    }
+
+    /**
+     * @return logout_serial_num
+     */
+    public Integer getLogoutSerialNum() {
+        return logoutSerialNum;
+    }
+
+    /**
+     * @param logoutSerialNum
+     */
+    public void setLogoutSerialNum(Integer logoutSerialNum) {
+        this.logoutSerialNum = logoutSerialNum;
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/DataStream.java b/src/main/kotlin/com/flightfeather/uav/domain/entity/DataStream.java
new file mode 100644
index 0000000..7c4034a
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/entity/DataStream.java
@@ -0,0 +1,551 @@
+package com.flightfeather.uav.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "obd_data_stream")
+public class DataStream {
+    @Id
+    private Integer id;
+
+    @Column(name = "obd_device_code")
+    private String obdDeviceCode;
+
+    @Column(name = "obd_create_time")
+    private Date obdCreateTime;
+
+    @Column(name = "obd_data_time")
+    private Date obdDataTime;
+
+    @Column(name = "obd_serial_num")
+    private Integer obdSerialNum;
+
+    @Column(name = "obd_speed")
+    private Double obdSpeed;
+
+    @Column(name = "obd_air_pressure")
+    private Double obdAirPressure;
+
+    @Column(name = "obd_engine_torque")
+    private Double obdEngineTorque;
+
+    @Column(name = "obd_friction_torque")
+    private Double obdFrictionTorque;
+
+    @Column(name = "obd_engine_rpm")
+    private Double obdEngineRpm;
+
+    @Column(name = "obd_engine_fuel_flow")
+    private Double obdEngineFuelFlow;
+
+    @Column(name = "obd_scr_upstream_NOx")
+    private Double obdScrUpstreamNox;
+
+    @Column(name = "obd_scr_downstream_NOx")
+    private Double obdScrDownstreamNox;
+
+    @Column(name = "obd_remain_reactant")
+    private Double obdRemainReactant;
+
+    @Column(name = "obd_air_input")
+    private Double obdAirInput;
+
+    @Column(name = "obd_scr_input_temp")
+    private Double obdScrInputTemp;
+
+    @Column(name = "obd_scr_output_temp")
+    private Double obdScrOutputTemp;
+
+    @Column(name = "obd_DPF")
+    private Double obdDpf;
+
+    @Column(name = "obd_engine_coolant_temp")
+    private Double obdEngineCoolantTemp;
+
+    @Column(name = "obd_fuel_level")
+    private Double obdFuelLevel;
+
+    @Column(name = "obd_location_status")
+    private String obdLocationStatus;
+
+    @Column(name = "obd_long")
+    private Double obdLong;
+
+    @Column(name = "obd_lat")
+    private Double obdLat;
+
+    @Column(name = "obd_total_mileage")
+    private Double obdTotalMileage;
+
+    @Column(name = "obd_engine_torque_mode")
+    private Integer obdEngineTorqueMode;
+
+    @Column(name = "obd_accelerator_pedal")
+    private Double obdAcceleratorPedal;
+
+    @Column(name = "obd_total_oil_consumption")
+    private Double obdTotalOilConsumption;
+
+    @Column(name = "obd_urea_box_temp")
+    private Double obdUreaBoxTemp;
+
+    @Column(name = "obd_urea_volume")
+    private Double obdUreaVolume;
+
+    @Column(name = "obd_total_urea_consume")
+    private Double obdTotalUreaConsume;
+
+    @Column(name = "obd_DPF_temp")
+    private Double obdDpfTemp;
+
+    @Column(name = "obd_status")
+    private Boolean obdStatus;
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * @return obd_device_code
+     */
+    public String getObdDeviceCode() {
+        return obdDeviceCode;
+    }
+
+    /**
+     * @param obdDeviceCode
+     */
+    public void setObdDeviceCode(String obdDeviceCode) {
+        this.obdDeviceCode = obdDeviceCode == null ? null : obdDeviceCode.trim();
+    }
+
+    /**
+     * @return obd_create_time
+     */
+    public Date getObdCreateTime() {
+        return obdCreateTime;
+    }
+
+    /**
+     * @param obdCreateTime
+     */
+    public void setObdCreateTime(Date obdCreateTime) {
+        this.obdCreateTime = obdCreateTime;
+    }
+
+    /**
+     * @return obd_data_time
+     */
+    public Date getObdDataTime() {
+        return obdDataTime;
+    }
+
+    /**
+     * @param obdDataTime
+     */
+    public void setObdDataTime(Date obdDataTime) {
+        this.obdDataTime = obdDataTime;
+    }
+
+    /**
+     * @return obd_serial_num
+     */
+    public Integer getObdSerialNum() {
+        return obdSerialNum;
+    }
+
+    /**
+     * @param obdSerialNum
+     */
+    public void setObdSerialNum(Integer obdSerialNum) {
+        this.obdSerialNum = obdSerialNum;
+    }
+
+    /**
+     * @return obd_speed
+     */
+    public Double getObdSpeed() {
+        return obdSpeed;
+    }
+
+    /**
+     * @param obdSpeed
+     */
+    public void setObdSpeed(Double obdSpeed) {
+        this.obdSpeed = obdSpeed;
+    }
+
+    /**
+     * @return obd_air_pressure
+     */
+    public Double getObdAirPressure() {
+        return obdAirPressure;
+    }
+
+    /**
+     * @param obdAirPressure
+     */
+    public void setObdAirPressure(Double obdAirPressure) {
+        this.obdAirPressure = obdAirPressure;
+    }
+
+    /**
+     * @return obd_engine_torque
+     */
+    public Double getObdEngineTorque() {
+        return obdEngineTorque;
+    }
+
+    /**
+     * @param obdEngineTorque
+     */
+    public void setObdEngineTorque(Double obdEngineTorque) {
+        this.obdEngineTorque = obdEngineTorque;
+    }
+
+    /**
+     * @return obd_friction_torque
+     */
+    public Double getObdFrictionTorque() {
+        return obdFrictionTorque;
+    }
+
+    /**
+     * @param obdFrictionTorque
+     */
+    public void setObdFrictionTorque(Double obdFrictionTorque) {
+        this.obdFrictionTorque = obdFrictionTorque;
+    }
+
+    /**
+     * @return obd_engine_rpm
+     */
+    public Double getObdEngineRpm() {
+        return obdEngineRpm;
+    }
+
+    /**
+     * @param obdEngineRpm
+     */
+    public void setObdEngineRpm(Double obdEngineRpm) {
+        this.obdEngineRpm = obdEngineRpm;
+    }
+
+    /**
+     * @return obd_engine_fuel_flow
+     */
+    public Double getObdEngineFuelFlow() {
+        return obdEngineFuelFlow;
+    }
+
+    /**
+     * @param obdEngineFuelFlow
+     */
+    public void setObdEngineFuelFlow(Double obdEngineFuelFlow) {
+        this.obdEngineFuelFlow = obdEngineFuelFlow;
+    }
+
+    /**
+     * @return obd_scr_upstream_NOx
+     */
+    public Double getObdScrUpstreamNox() {
+        return obdScrUpstreamNox;
+    }
+
+    /**
+     * @param obdScrUpstreamNox
+     */
+    public void setObdScrUpstreamNox(Double obdScrUpstreamNox) {
+        this.obdScrUpstreamNox = obdScrUpstreamNox;
+    }
+
+    /**
+     * @return obd_scr_downstream_NOx
+     */
+    public Double getObdScrDownstreamNox() {
+        return obdScrDownstreamNox;
+    }
+
+    /**
+     * @param obdScrDownstreamNox
+     */
+    public void setObdScrDownstreamNox(Double obdScrDownstreamNox) {
+        this.obdScrDownstreamNox = obdScrDownstreamNox;
+    }
+
+    /**
+     * @return obd_remain_reactant
+     */
+    public Double getObdRemainReactant() {
+        return obdRemainReactant;
+    }
+
+    /**
+     * @param obdRemainReactant
+     */
+    public void setObdRemainReactant(Double obdRemainReactant) {
+        this.obdRemainReactant = obdRemainReactant;
+    }
+
+    /**
+     * @return obd_air_input
+     */
+    public Double getObdAirInput() {
+        return obdAirInput;
+    }
+
+    /**
+     * @param obdAirInput
+     */
+    public void setObdAirInput(Double obdAirInput) {
+        this.obdAirInput = obdAirInput;
+    }
+
+    /**
+     * @return obd_scr_input_temp
+     */
+    public Double getObdScrInputTemp() {
+        return obdScrInputTemp;
+    }
+
+    /**
+     * @param obdScrInputTemp
+     */
+    public void setObdScrInputTemp(Double obdScrInputTemp) {
+        this.obdScrInputTemp = obdScrInputTemp;
+    }
+
+    /**
+     * @return obd_scr_output_temp
+     */
+    public Double getObdScrOutputTemp() {
+        return obdScrOutputTemp;
+    }
+
+    /**
+     * @param obdScrOutputTemp
+     */
+    public void setObdScrOutputTemp(Double obdScrOutputTemp) {
+        this.obdScrOutputTemp = obdScrOutputTemp;
+    }
+
+    /**
+     * @return obd_DPF
+     */
+    public Double getObdDpf() {
+        return obdDpf;
+    }
+
+    /**
+     * @param obdDpf
+     */
+    public void setObdDpf(Double obdDpf) {
+        this.obdDpf = obdDpf;
+    }
+
+    /**
+     * @return obd_engine_coolant_temp
+     */
+    public Double getObdEngineCoolantTemp() {
+        return obdEngineCoolantTemp;
+    }
+
+    /**
+     * @param obdEngineCoolantTemp
+     */
+    public void setObdEngineCoolantTemp(Double obdEngineCoolantTemp) {
+        this.obdEngineCoolantTemp = obdEngineCoolantTemp;
+    }
+
+    /**
+     * @return obd_fuel_level
+     */
+    public Double getObdFuelLevel() {
+        return obdFuelLevel;
+    }
+
+    /**
+     * @param obdFuelLevel
+     */
+    public void setObdFuelLevel(Double obdFuelLevel) {
+        this.obdFuelLevel = obdFuelLevel;
+    }
+
+    /**
+     * @return obd_location_status
+     */
+    public String getObdLocationStatus() {
+        return obdLocationStatus;
+    }
+
+    /**
+     * @param obdLocationStatus
+     */
+    public void setObdLocationStatus(String obdLocationStatus) {
+        this.obdLocationStatus = obdLocationStatus == null ? null : obdLocationStatus.trim();
+    }
+
+    /**
+     * @return obd_long
+     */
+    public Double getObdLong() {
+        return obdLong;
+    }
+
+    /**
+     * @param obdLong
+     */
+    public void setObdLong(Double obdLong) {
+        this.obdLong = obdLong;
+    }
+
+    /**
+     * @return obd_lat
+     */
+    public Double getObdLat() {
+        return obdLat;
+    }
+
+    /**
+     * @param obdLat
+     */
+    public void setObdLat(Double obdLat) {
+        this.obdLat = obdLat;
+    }
+
+    /**
+     * @return obd_total_mileage
+     */
+    public Double getObdTotalMileage() {
+        return obdTotalMileage;
+    }
+
+    /**
+     * @param obdTotalMileage
+     */
+    public void setObdTotalMileage(Double obdTotalMileage) {
+        this.obdTotalMileage = obdTotalMileage;
+    }
+
+    /**
+     * @return obd_engine_torque_mode
+     */
+    public Integer getObdEngineTorqueMode() {
+        return obdEngineTorqueMode;
+    }
+
+    /**
+     * @param obdEngineTorqueMode
+     */
+    public void setObdEngineTorqueMode(Integer obdEngineTorqueMode) {
+        this.obdEngineTorqueMode = obdEngineTorqueMode;
+    }
+
+    /**
+     * @return obd_accelerator_pedal
+     */
+    public Double getObdAcceleratorPedal() {
+        return obdAcceleratorPedal;
+    }
+
+    /**
+     * @param obdAcceleratorPedal
+     */
+    public void setObdAcceleratorPedal(Double obdAcceleratorPedal) {
+        this.obdAcceleratorPedal = obdAcceleratorPedal;
+    }
+
+    /**
+     * @return obd_total_oil_consumption
+     */
+    public Double getObdTotalOilConsumption() {
+        return obdTotalOilConsumption;
+    }
+
+    /**
+     * @param obdTotalOilConsumption
+     */
+    public void setObdTotalOilConsumption(Double obdTotalOilConsumption) {
+        this.obdTotalOilConsumption = obdTotalOilConsumption;
+    }
+
+    /**
+     * @return obd_urea_box_temp
+     */
+    public Double getObdUreaBoxTemp() {
+        return obdUreaBoxTemp;
+    }
+
+    /**
+     * @param obdUreaBoxTemp
+     */
+    public void setObdUreaBoxTemp(Double obdUreaBoxTemp) {
+        this.obdUreaBoxTemp = obdUreaBoxTemp;
+    }
+
+    /**
+     * @return obd_urea_volume
+     */
+    public Double getObdUreaVolume() {
+        return obdUreaVolume;
+    }
+
+    /**
+     * @param obdUreaVolume
+     */
+    public void setObdUreaVolume(Double obdUreaVolume) {
+        this.obdUreaVolume = obdUreaVolume;
+    }
+
+    /**
+     * @return obd_total_urea_consume
+     */
+    public Double getObdTotalUreaConsume() {
+        return obdTotalUreaConsume;
+    }
+
+    /**
+     * @param obdTotalUreaConsume
+     */
+    public void setObdTotalUreaConsume(Double obdTotalUreaConsume) {
+        this.obdTotalUreaConsume = obdTotalUreaConsume;
+    }
+
+    /**
+     * @return obd_DPF_temp
+     */
+    public Double getObdDpfTemp() {
+        return obdDpfTemp;
+    }
+
+    /**
+     * @param obdDpfTemp
+     */
+    public void setObdDpfTemp(Double obdDpfTemp) {
+        this.obdDpfTemp = obdDpfTemp;
+    }
+
+    /**
+     * @return obd_status
+     */
+    public Boolean getObdStatus() {
+        return obdStatus;
+    }
+
+    /**
+     * @param obdStatus
+     */
+    public void setObdStatus(Boolean obdStatus) {
+        this.obdStatus = obdStatus;
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/ObdData.java b/src/main/kotlin/com/flightfeather/uav/domain/entity/ObdData.java
new file mode 100644
index 0000000..468aaae
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/entity/ObdData.java
@@ -0,0 +1,622 @@
+package com.flightfeather.uav.domain.entity;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "obd_data")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ObdData {
+    @Id
+    private Integer id;
+
+    @Column(name = "obd_vin")
+    private String obdVin;
+
+    @Column(name = "obd_time")
+    private Date obdTime;
+
+    @Column(name = "obd_lng")
+    private Double obdLng;
+
+    @Column(name = "obd_lat")
+    private Double obdLat;
+
+    @Column(name = "obd_protocol")
+    private Integer obdProtocol;
+
+    @Column(name = "obd_mil")
+    private Integer obdMil;
+
+    @Column(name = "obd_id_code")
+    private String obdIdCode;
+
+    @Column(name = "obd_verification_code")
+    private String obdVerificationCode;
+
+    @Column(name = "obd_fault_code_num")
+    private Integer obdFaultCodeNum;
+
+    @Column(name = "obd_fault_code")
+    private String obdFaultCode;
+
+    @Column(name = "obd_speed")
+    private Integer obdSpeed;
+
+    @Column(name = "obd_air_pressure")
+    private Double obdAirPressure;
+
+    @Column(name = "obd_engine_torque")
+    private Double obdEngineTorque;
+
+    @Column(name = "obd_friction_torque")
+    private Double obdFrictionTorque;
+
+    @Column(name = "obd_engine_rpm")
+    private Integer obdEngineRpm;
+
+    @Column(name = "obd_start_fuel_flow")
+    private Double obdStartFuelFlow;
+
+    @Column(name = "obd_scr_upstream_NO")
+    private Double obdScrUpstreamNo;
+
+    @Column(name = "obd_scr_downstream_NO")
+    private Double obdScrDownstreamNo;
+
+    @Column(name = "obd_remain_reactant")
+    private Double obdRemainReactant;
+
+    @Column(name = "obd_air_input")
+    private Double obdAirInput;
+
+    @Column(name = "obd_scr_input_temp")
+    private Double obdScrInputTemp;
+
+    @Column(name = "obd_scr_output_temp")
+    private Double obdScrOutputTemp;
+
+    @Column(name = "obd_DPF")
+    private Double obdDpf;
+
+    @Column(name = "obd_engine_coolant_temp")
+    private Double obdEngineCoolantTemp;
+
+    @Column(name = "obd_fuel_level")
+    private Double obdFuelLevel;
+
+    @Column(name = "obd_location_status")
+    private Integer obdLocationStatus;
+
+    @Column(name = "obd_total_mileage")
+    private Double obdTotalMileage;
+
+    @Column(name = "obd_engine_torque_mode")
+    private String obdEngineTorqueMode;
+
+    @Column(name = "obd_accelerator_pedal")
+    private Double obdAcceleratorPedal;
+
+    @Column(name = "obd_total_oil_consumption")
+    private Double obdTotalOilConsumption;
+
+    @Column(name = "obd_urea_box_temp")
+    private Double obdUreaBoxTemp;
+
+    @Column(name = "obd_urea_volume")
+    private Integer obdUreaVolume;
+
+    @Column(name = "obd_total_urea_consume")
+    private Double obdTotalUreaConsume;
+
+    @Column(name = "obd_DPF_temp")
+    private Double obdDpfTemp;
+
+    @Column(name = "obd_firmware_version")
+    private String obdFirmwareVersion;
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * @return obd_vin
+     */
+    public String getObdVin() {
+        return obdVin;
+    }
+
+    /**
+     * @param obdVin
+     */
+    public void setObdVin(String obdVin) {
+        this.obdVin = obdVin == null ? null : obdVin.trim();
+    }
+
+    /**
+     * @return obd_time
+     */
+    public Date getObdTime() {
+        return obdTime;
+    }
+
+    /**
+     * @param obdTime
+     */
+    public void setObdTime(Date obdTime) {
+        this.obdTime = obdTime;
+    }
+
+    /**
+     * @return obd_lng
+     */
+    public Double getObdLng() {
+        return obdLng;
+    }
+
+    /**
+     * @param obdLng
+     */
+    public void setObdLng(Double obdLng) {
+        this.obdLng = obdLng;
+    }
+
+    /**
+     * @return obd_lat
+     */
+    public Double getObdLat() {
+        return obdLat;
+    }
+
+    /**
+     * @param obdLat
+     */
+    public void setObdLat(Double obdLat) {
+        this.obdLat = obdLat;
+    }
+
+    /**
+     * @return obd_protocol
+     */
+    public Integer getObdProtocol() {
+        return obdProtocol;
+    }
+
+    /**
+     * @param obdProtocol
+     */
+    public void setObdProtocol(Integer obdProtocol) {
+        this.obdProtocol = obdProtocol;
+    }
+
+    /**
+     * @return obd_mil
+     */
+    public Integer getObdMil() {
+        return obdMil;
+    }
+
+    /**
+     * @param obdMil
+     */
+    public void setObdMil(Integer obdMil) {
+        this.obdMil = obdMil;
+    }
+
+    /**
+     * @return obd_id_code
+     */
+    public String getObdIdCode() {
+        return obdIdCode;
+    }
+
+    /**
+     * @param obdIdCode
+     */
+    public void setObdIdCode(String obdIdCode) {
+        this.obdIdCode = obdIdCode == null ? null : obdIdCode.trim();
+    }
+
+    /**
+     * @return obd_verification_code
+     */
+    public String getObdVerificationCode() {
+        return obdVerificationCode;
+    }
+
+    /**
+     * @param obdVerificationCode
+     */
+    public void setObdVerificationCode(String obdVerificationCode) {
+        this.obdVerificationCode = obdVerificationCode == null ? null : obdVerificationCode.trim();
+    }
+
+    /**
+     * @return obd_fault_code_num
+     */
+    public Integer getObdFaultCodeNum() {
+        return obdFaultCodeNum;
+    }
+
+    /**
+     * @param obdFaultCodeNum
+     */
+    public void setObdFaultCodeNum(Integer obdFaultCodeNum) {
+        this.obdFaultCodeNum = obdFaultCodeNum;
+    }
+
+    /**
+     * @return obd_fault_code
+     */
+    public String getObdFaultCode() {
+        return obdFaultCode;
+    }
+
+    /**
+     * @param obdFaultCode
+     */
+    public void setObdFaultCode(String obdFaultCode) {
+        this.obdFaultCode = obdFaultCode == null ? null : obdFaultCode.trim();
+    }
+
+    /**
+     * @return obd_speed
+     */
+    public Integer getObdSpeed() {
+        return obdSpeed;
+    }
+
+    /**
+     * @param obdSpeed
+     */
+    public void setObdSpeed(Integer obdSpeed) {
+        this.obdSpeed = obdSpeed;
+    }
+
+    /**
+     * @return obd_air_pressure
+     */
+    public Double getObdAirPressure() {
+        return obdAirPressure;
+    }
+
+    /**
+     * @param obdAirPressure
+     */
+    public void setObdAirPressure(Double obdAirPressure) {
+        this.obdAirPressure = obdAirPressure;
+    }
+
+    /**
+     * @return obd_engine_torque
+     */
+    public Double getObdEngineTorque() {
+        return obdEngineTorque;
+    }
+
+    /**
+     * @param obdEngineTorque
+     */
+    public void setObdEngineTorque(Double obdEngineTorque) {
+        this.obdEngineTorque = obdEngineTorque;
+    }
+
+    /**
+     * @return obd_friction_torque
+     */
+    public Double getObdFrictionTorque() {
+        return obdFrictionTorque;
+    }
+
+    /**
+     * @param obdFrictionTorque
+     */
+    public void setObdFrictionTorque(Double obdFrictionTorque) {
+        this.obdFrictionTorque = obdFrictionTorque;
+    }
+
+    /**
+     * @return obd_engine_rpm
+     */
+    public Integer getObdEngineRpm() {
+        return obdEngineRpm;
+    }
+
+    /**
+     * @param obdEngineRpm
+     */
+    public void setObdEngineRpm(Integer obdEngineRpm) {
+        this.obdEngineRpm = obdEngineRpm;
+    }
+
+    /**
+     * @return obd_start_fuel_flow
+     */
+    public Double getObdStartFuelFlow() {
+        return obdStartFuelFlow;
+    }
+
+    /**
+     * @param obdStartFuelFlow
+     */
+    public void setObdStartFuelFlow(Double obdStartFuelFlow) {
+        this.obdStartFuelFlow = obdStartFuelFlow;
+    }
+
+    /**
+     * @return obd_scr_upstream_NO
+     */
+    public Double getObdScrUpstreamNo() {
+        return obdScrUpstreamNo;
+    }
+
+    /**
+     * @param obdScrUpstreamNo
+     */
+    public void setObdScrUpstreamNo(Double obdScrUpstreamNo) {
+        this.obdScrUpstreamNo = obdScrUpstreamNo;
+    }
+
+    /**
+     * @return obd_scr_downstream_NO
+     */
+    public Double getObdScrDownstreamNo() {
+        return obdScrDownstreamNo;
+    }
+
+    /**
+     * @param obdScrDownstreamNo
+     */
+    public void setObdScrDownstreamNo(Double obdScrDownstreamNo) {
+        this.obdScrDownstreamNo = obdScrDownstreamNo;
+    }
+
+    /**
+     * @return obd_remain_reactant
+     */
+    public Double getObdRemainReactant() {
+        return obdRemainReactant;
+    }
+
+    /**
+     * @param obdRemainReactant
+     */
+    public void setObdRemainReactant(Double obdRemainReactant) {
+        this.obdRemainReactant = obdRemainReactant;
+    }
+
+    /**
+     * @return obd_air_input
+     */
+    public Double getObdAirInput() {
+        return obdAirInput;
+    }
+
+    /**
+     * @param obdAirInput
+     */
+    public void setObdAirInput(Double obdAirInput) {
+        this.obdAirInput = obdAirInput;
+    }
+
+    /**
+     * @return obd_scr_input_temp
+     */
+    public Double getObdScrInputTemp() {
+        return obdScrInputTemp;
+    }
+
+    /**
+     * @param obdScrInputTemp
+     */
+    public void setObdScrInputTemp(Double obdScrInputTemp) {
+        this.obdScrInputTemp = obdScrInputTemp;
+    }
+
+    /**
+     * @return obd_scr_output_temp
+     */
+    public Double getObdScrOutputTemp() {
+        return obdScrOutputTemp;
+    }
+
+    /**
+     * @param obdScrOutputTemp
+     */
+    public void setObdScrOutputTemp(Double obdScrOutputTemp) {
+        this.obdScrOutputTemp = obdScrOutputTemp;
+    }
+
+    /**
+     * @return obd_DPF
+     */
+    public Double getObdDpf() {
+        return obdDpf;
+    }
+
+    /**
+     * @param obdDpf
+     */
+    public void setObdDpf(Double obdDpf) {
+        this.obdDpf = obdDpf;
+    }
+
+    /**
+     * @return obd_engine_coolant_temp
+     */
+    public Double getObdEngineCoolantTemp() {
+        return obdEngineCoolantTemp;
+    }
+
+    /**
+     * @param obdEngineCoolantTemp
+     */
+    public void setObdEngineCoolantTemp(Double obdEngineCoolantTemp) {
+        this.obdEngineCoolantTemp = obdEngineCoolantTemp;
+    }
+
+    /**
+     * @return obd_fuel_level
+     */
+    public Double getObdFuelLevel() {
+        return obdFuelLevel;
+    }
+
+    /**
+     * @param obdFuelLevel
+     */
+    public void setObdFuelLevel(Double obdFuelLevel) {
+        this.obdFuelLevel = obdFuelLevel;
+    }
+
+    /**
+     * @return obd_location_status
+     */
+    public Integer getObdLocationStatus() {
+        return obdLocationStatus;
+    }
+
+    /**
+     * @param obdLocationStatus
+     */
+    public void setObdLocationStatus(Integer obdLocationStatus) {
+        this.obdLocationStatus = obdLocationStatus;
+    }
+
+    /**
+     * @return obd_total_mileage
+     */
+    public Double getObdTotalMileage() {
+        return obdTotalMileage;
+    }
+
+    /**
+     * @param obdTotalMileage
+     */
+    public void setObdTotalMileage(Double obdTotalMileage) {
+        this.obdTotalMileage = obdTotalMileage;
+    }
+
+    /**
+     * @return obd_engine_torque_mode
+     */
+    public String getObdEngineTorqueMode() {
+        return obdEngineTorqueMode;
+    }
+
+    /**
+     * @param obdEngineTorqueMode
+     */
+    public void setObdEngineTorqueMode(String obdEngineTorqueMode) {
+        this.obdEngineTorqueMode = obdEngineTorqueMode == null ? null : obdEngineTorqueMode.trim();
+    }
+
+    /**
+     * @return obd_accelerator_pedal
+     */
+    public Double getObdAcceleratorPedal() {
+        return obdAcceleratorPedal;
+    }
+
+    /**
+     * @param obdAcceleratorPedal
+     */
+    public void setObdAcceleratorPedal(Double obdAcceleratorPedal) {
+        this.obdAcceleratorPedal = obdAcceleratorPedal;
+    }
+
+    /**
+     * @return obd_total_oil_consumption
+     */
+    public Double getObdTotalOilConsumption() {
+        return obdTotalOilConsumption;
+    }
+
+    /**
+     * @param obdTotalOilConsumption
+     */
+    public void setObdTotalOilConsumption(Double obdTotalOilConsumption) {
+        this.obdTotalOilConsumption = obdTotalOilConsumption;
+    }
+
+    /**
+     * @return obd_urea_box_temp
+     */
+    public Double getObdUreaBoxTemp() {
+        return obdUreaBoxTemp;
+    }
+
+    /**
+     * @param obdUreaBoxTemp
+     */
+    public void setObdUreaBoxTemp(Double obdUreaBoxTemp) {
+        this.obdUreaBoxTemp = obdUreaBoxTemp;
+    }
+
+    /**
+     * @return obd_urea_volume
+     */
+    public Integer getObdUreaVolume() {
+        return obdUreaVolume;
+    }
+
+    /**
+     * @param obdUreaVolume
+     */
+    public void setObdUreaVolume(Integer obdUreaVolume) {
+        this.obdUreaVolume = obdUreaVolume;
+    }
+
+    /**
+     * @return obd_total_urea_consume
+     */
+    public Double getObdTotalUreaConsume() {
+        return obdTotalUreaConsume;
+    }
+
+    /**
+     * @param obdTotalUreaConsume
+     */
+    public void setObdTotalUreaConsume(Double obdTotalUreaConsume) {
+        this.obdTotalUreaConsume = obdTotalUreaConsume;
+    }
+
+    /**
+     * @return obd_DPF_temp
+     */
+    public Double getObdDpfTemp() {
+        return obdDpfTemp;
+    }
+
+    /**
+     * @param obdDpfTemp
+     */
+    public void setObdDpfTemp(Double obdDpfTemp) {
+        this.obdDpfTemp = obdDpfTemp;
+    }
+
+    /**
+     * @return obd_firmware_version
+     */
+    public String getObdFirmwareVersion() {
+        return obdFirmwareVersion;
+    }
+
+    /**
+     * @param obdFirmwareVersion
+     */
+    public void setObdFirmwareVersion(String obdFirmwareVersion) {
+        this.obdFirmwareVersion = obdFirmwareVersion == null ? null : obdFirmwareVersion.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/ObdInfo.java b/src/main/kotlin/com/flightfeather/uav/domain/entity/ObdInfo.java
new file mode 100644
index 0000000..b23c6d7
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/entity/ObdInfo.java
@@ -0,0 +1,279 @@
+package com.flightfeather.uav.domain.entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "obd_info")
+public class ObdInfo {
+    @Id
+    private Integer id;
+
+    @Column(name = "obd_device_code")
+    private String obdDeviceCode;
+
+    @Column(name = "obd_create_time")
+    private Date obdCreateTime;
+
+    @Column(name = "obd_data_time")
+    private Date obdDataTime;
+
+    @Column(name = "obd_serial_num")
+    private Integer obdSerialNum;
+
+    @Column(name = "obd_protocol")
+    private Integer obdProtocol;
+
+    @Column(name = "obd_mil")
+    private Integer obdMil;
+
+    @Column(name = "obd_diagnosis_support_status")
+    private String obdDiagnosisSupportStatus;
+
+    @Column(name = "obd_diagnosis_ready_status")
+    private String obdDiagnosisReadyStatus;
+
+    @Column(name = "obd_vin")
+    private String obdVin;
+
+    @Column(name = "obd_crn")
+    private String obdCrn;
+
+    @Column(name = "obd_cvn")
+    private String obdCvn;
+
+    @Column(name = "obd_iupr")
+    private String obdIupr;
+
+    @Column(name = "obd_fault_code_num")
+    private Integer obdFaultCodeNum;
+
+    @Column(name = "obd_fault_code")
+    private String obdFaultCode;
+
+    @Column(name = "obd_status")
+    private Boolean obdStatus;
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * @return obd_device_code
+     */
+    public String getObdDeviceCode() {
+        return obdDeviceCode;
+    }
+
+    /**
+     * @param obdDeviceCode
+     */
+    public void setObdDeviceCode(String obdDeviceCode) {
+        this.obdDeviceCode = obdDeviceCode == null ? null : obdDeviceCode.trim();
+    }
+
+    /**
+     * @return obd_create_time
+     */
+    public Date getObdCreateTime() {
+        return obdCreateTime;
+    }
+
+    /**
+     * @param obdCreateTime
+     */
+    public void setObdCreateTime(Date obdCreateTime) {
+        this.obdCreateTime = obdCreateTime;
+    }
+
+    /**
+     * @return obd_data_time
+     */
+    public Date getObdDataTime() {
+        return obdDataTime;
+    }
+
+    /**
+     * @param obdDataTime
+     */
+    public void setObdDataTime(Date obdDataTime) {
+        this.obdDataTime = obdDataTime;
+    }
+
+    /**
+     * @return obd_serial_num
+     */
+    public Integer getObdSerialNum() {
+        return obdSerialNum;
+    }
+
+    /**
+     * @param obdSerialNum
+     */
+    public void setObdSerialNum(Integer obdSerialNum) {
+        this.obdSerialNum = obdSerialNum;
+    }
+
+    /**
+     * @return obd_protocol
+     */
+    public Integer getObdProtocol() {
+        return obdProtocol;
+    }
+
+    /**
+     * @param obdProtocol
+     */
+    public void setObdProtocol(Integer obdProtocol) {
+        this.obdProtocol = obdProtocol;
+    }
+
+    /**
+     * @return obd_mil
+     */
+    public Integer getObdMil() {
+        return obdMil;
+    }
+
+    /**
+     * @param obdMil
+     */
+    public void setObdMil(Integer obdMil) {
+        this.obdMil = obdMil;
+    }
+
+    /**
+     * @return obd_diagnosis_support_status
+     */
+    public String getObdDiagnosisSupportStatus() {
+        return obdDiagnosisSupportStatus;
+    }
+
+    /**
+     * @param obdDiagnosisSupportStatus
+     */
+    public void setObdDiagnosisSupportStatus(String obdDiagnosisSupportStatus) {
+        this.obdDiagnosisSupportStatus = obdDiagnosisSupportStatus == null ? null : obdDiagnosisSupportStatus.trim();
+    }
+
+    /**
+     * @return obd_diagnosis_ready_status
+     */
+    public String getObdDiagnosisReadyStatus() {
+        return obdDiagnosisReadyStatus;
+    }
+
+    /**
+     * @param obdDiagnosisReadyStatus
+     */
+    public void setObdDiagnosisReadyStatus(String obdDiagnosisReadyStatus) {
+        this.obdDiagnosisReadyStatus = obdDiagnosisReadyStatus == null ? null : obdDiagnosisReadyStatus.trim();
+    }
+
+    /**
+     * @return obd_vin
+     */
+    public String getObdVin() {
+        return obdVin;
+    }
+
+    /**
+     * @param obdVin
+     */
+    public void setObdVin(String obdVin) {
+        this.obdVin = obdVin == null ? null : obdVin.trim();
+    }
+
+    /**
+     * @return obd_crn
+     */
+    public String getObdCrn() {
+        return obdCrn;
+    }
+
+    /**
+     * @param obdCrn
+     */
+    public void setObdCrn(String obdCrn) {
+        this.obdCrn = obdCrn == null ? null : obdCrn.trim();
+    }
+
+    /**
+     * @return obd_cvn
+     */
+    public String getObdCvn() {
+        return obdCvn;
+    }
+
+    /**
+     * @param obdCvn
+     */
+    public void setObdCvn(String obdCvn) {
+        this.obdCvn = obdCvn == null ? null : obdCvn.trim();
+    }
+
+    /**
+     * @return obd_iupr
+     */
+    public String getObdIupr() {
+        return obdIupr;
+    }
+
+    /**
+     * @param obdIupr
+     */
+    public void setObdIupr(String obdIupr) {
+        this.obdIupr = obdIupr == null ? null : obdIupr.trim();
+    }
+
+    /**
+     * @return obd_fault_code_num
+     */
+    public Integer getObdFaultCodeNum() {
+        return obdFaultCodeNum;
+    }
+
+    /**
+     * @param obdFaultCodeNum
+     */
+    public void setObdFaultCodeNum(Integer obdFaultCodeNum) {
+        this.obdFaultCodeNum = obdFaultCodeNum;
+    }
+
+    /**
+     * @return obd_fault_code
+     */
+    public String getObdFaultCode() {
+        return obdFaultCode;
+    }
+
+    /**
+     * @param obdFaultCode
+     */
+    public void setObdFaultCode(String obdFaultCode) {
+        this.obdFaultCode = obdFaultCode == null ? null : obdFaultCode.trim();
+    }
+
+    /**
+     * @return obd_status
+     */
+    public Boolean getObdStatus() {
+        return obdStatus;
+    }
+
+    /**
+     * @param obdStatus
+     */
+    public void setObdStatus(Boolean obdStatus) {
+        this.obdStatus = obdStatus;
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/ObdUser.java b/src/main/kotlin/com/flightfeather/uav/domain/entity/ObdUser.java
new file mode 100644
index 0000000..4575a81
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/entity/ObdUser.java
@@ -0,0 +1,91 @@
+package com.flightfeather.uav.domain.entity;
+
+import javax.persistence.*;
+
+@Table(name = "obd_user")
+public class ObdUser {
+    @Id
+    private Integer id;
+
+    @Column(name = "obd_vin")
+    private String obdVin;
+
+    @Column(name = "obd_user_id")
+    private Double obdUserId;
+
+    @Column(name = "obd_user_name")
+    private String obdUserName;
+
+    @Column(name = "obd_user_password")
+    private String obdUserPassword;
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * @return obd_vin
+     */
+    public String getObdVin() {
+        return obdVin;
+    }
+
+    /**
+     * @param obdVin
+     */
+    public void setObdVin(String obdVin) {
+        this.obdVin = obdVin == null ? null : obdVin.trim();
+    }
+
+    /**
+     * @return obd_user_id
+     */
+    public Double getObdUserId() {
+        return obdUserId;
+    }
+
+    /**
+     * @param obdUserId
+     */
+    public void setObdUserId(Double obdUserId) {
+        this.obdUserId = obdUserId;
+    }
+
+    /**
+     * @return obd_user_name
+     */
+    public String getObdUserName() {
+        return obdUserName;
+    }
+
+    /**
+     * @param obdUserName
+     */
+    public void setObdUserName(String obdUserName) {
+        this.obdUserName = obdUserName == null ? null : obdUserName.trim();
+    }
+
+    /**
+     * @return obd_user_password
+     */
+    public String getObdUserPassword() {
+        return obdUserPassword;
+    }
+
+    /**
+     * @param obdUserPassword
+     */
+    public void setObdUserPassword(String obdUserPassword) {
+        this.obdUserPassword = obdUserPassword == null ? null : obdUserPassword.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/OriginData.java b/src/main/kotlin/com/flightfeather/uav/domain/entity/OriginData.java
new file mode 100644
index 0000000..8185848
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/entity/OriginData.java
@@ -0,0 +1,108 @@
+package com.flightfeather.uav.domain.entity;
+
+import javax.persistence.*;
+
+@Table(name = "obd_origin_data")
+public class OriginData {
+    @Id
+    private Integer id;
+
+    @Column(name = "obd_device_code")
+    private String obdDeviceCode;
+
+    @Column(name = "obd_terminal_software_version")
+    private Integer obdTerminalSoftwareVersion;
+
+    @Column(name = "obd_encryption_way")
+    private Integer obdEncryptionWay;
+
+    @Column(name = "obd_command_unit")
+    private Integer obdCommandUnit;
+
+    @Column(name = "obd_content")
+    private String obdContent;
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * @return obd_device_code
+     */
+    public String getObdDeviceCode() {
+        return obdDeviceCode;
+    }
+
+    /**
+     * @param obdDeviceCode
+     */
+    public void setObdDeviceCode(String obdDeviceCode) {
+        this.obdDeviceCode = obdDeviceCode == null ? null : obdDeviceCode.trim();
+    }
+
+    /**
+     * @return obd_terminal_software_version
+     */
+    public Integer getObdTerminalSoftwareVersion() {
+        return obdTerminalSoftwareVersion;
+    }
+
+    /**
+     * @param obdTerminalSoftwareVersion
+     */
+    public void setObdTerminalSoftwareVersion(Integer obdTerminalSoftwareVersion) {
+        this.obdTerminalSoftwareVersion = obdTerminalSoftwareVersion;
+    }
+
+    /**
+     * @return obd_encryption_way
+     */
+    public Integer getObdEncryptionWay() {
+        return obdEncryptionWay;
+    }
+
+    /**
+     * @param obdEncryptionWay
+     */
+    public void setObdEncryptionWay(Integer obdEncryptionWay) {
+        this.obdEncryptionWay = obdEncryptionWay;
+    }
+
+    /**
+     * @return obd_command_unit
+     */
+    public Integer getObdCommandUnit() {
+        return obdCommandUnit;
+    }
+
+    /**
+     * @param obdCommandUnit
+     */
+    public void setObdCommandUnit(Integer obdCommandUnit) {
+        this.obdCommandUnit = obdCommandUnit;
+    }
+
+    /**
+     * @return obd_content
+     */
+    public String getObdContent() {
+        return obdContent;
+    }
+
+    /**
+     * @param obdContent
+     */
+    public void setObdContent(String obdContent) {
+        this.obdContent = obdContent == null ? null : obdContent.trim();
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/ThresholdValue.java b/src/main/kotlin/com/flightfeather/uav/domain/entity/ThresholdValue.java
new file mode 100644
index 0000000..7defa1c
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/entity/ThresholdValue.java
@@ -0,0 +1,499 @@
+package com.flightfeather.uav.domain.entity;
+
+import javax.persistence.*;
+
+@Table(name = "obd_threshold_value")
+public class ThresholdValue {
+    @Id
+    private Integer id;
+
+    @Column(name = "obd_vin")
+    private String obdVin;
+
+    @Column(name = "th_mil")
+    private Integer thMil;
+
+    @Column(name = "th_fault_code_num")
+    private Integer thFaultCodeNum;
+
+    @Column(name = "th_fault_code")
+    private String thFaultCode;
+
+    @Column(name = "th_speed")
+    private Integer thSpeed;
+
+    @Column(name = "th_air_pressure")
+    private Double thAirPressure;
+
+    @Column(name = "th_engine_torque")
+    private Double thEngineTorque;
+
+    @Column(name = "th_friction_torque")
+    private Double thFrictionTorque;
+
+    @Column(name = "th_engine_rpm")
+    private Integer thEngineRpm;
+
+    @Column(name = "th_start_fuel_flow")
+    private Double thStartFuelFlow;
+
+    @Column(name = "th_scr_upstream_NO")
+    private Double thScrUpstreamNo;
+
+    @Column(name = "th_scr_downstream_NO")
+    private Double thScrDownstreamNo;
+
+    @Column(name = "th_remain_reactant")
+    private Double thRemainReactant;
+
+    @Column(name = "th_air_input")
+    private Double thAirInput;
+
+    @Column(name = "th_scr_input_temp")
+    private Double thScrInputTemp;
+
+    @Column(name = "th_scr_output_temp")
+    private Double thScrOutputTemp;
+
+    @Column(name = "th_DPF")
+    private Double thDpf;
+
+    @Column(name = "th_engine_coolant_temp")
+    private Double thEngineCoolantTemp;
+
+    @Column(name = "th_fuel_level")
+    private Double thFuelLevel;
+
+    @Column(name = "th_location_status")
+    private Integer thLocationStatus;
+
+    @Column(name = "th_total_mileage")
+    private Double thTotalMileage;
+
+    @Column(name = "th_engine_torque_mode")
+    private String thEngineTorqueMode;
+
+    @Column(name = "th_accelerator_pedal")
+    private Double thAcceleratorPedal;
+
+    @Column(name = "th_total_oil_consumption")
+    private Double thTotalOilConsumption;
+
+    @Column(name = "th_urea_box_temp")
+    private Double thUreaBoxTemp;
+
+    @Column(name = "th_urea_volume")
+    private Integer thUreaVolume;
+
+    @Column(name = "th_total_urea_consume")
+    private Double thTotalUreaConsume;
+
+    @Column(name = "th_DPF_temp")
+    private Double thDpfTemp;
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * @return obd_vin
+     */
+    public String getObdVin() {
+        return obdVin;
+    }
+
+    /**
+     * @param obdVin
+     */
+    public void setObdVin(String obdVin) {
+        this.obdVin = obdVin == null ? null : obdVin.trim();
+    }
+
+    /**
+     * @return th_mil
+     */
+    public Integer getThMil() {
+        return thMil;
+    }
+
+    /**
+     * @param thMil
+     */
+    public void setThMil(Integer thMil) {
+        this.thMil = thMil;
+    }
+
+    /**
+     * @return th_fault_code_num
+     */
+    public Integer getThFaultCodeNum() {
+        return thFaultCodeNum;
+    }
+
+    /**
+     * @param thFaultCodeNum
+     */
+    public void setThFaultCodeNum(Integer thFaultCodeNum) {
+        this.thFaultCodeNum = thFaultCodeNum;
+    }
+
+    /**
+     * @return th_fault_code
+     */
+    public String getThFaultCode() {
+        return thFaultCode;
+    }
+
+    /**
+     * @param thFaultCode
+     */
+    public void setThFaultCode(String thFaultCode) {
+        this.thFaultCode = thFaultCode == null ? null : thFaultCode.trim();
+    }
+
+    /**
+     * @return th_speed
+     */
+    public Integer getThSpeed() {
+        return thSpeed;
+    }
+
+    /**
+     * @param thSpeed
+     */
+    public void setThSpeed(Integer thSpeed) {
+        this.thSpeed = thSpeed;
+    }
+
+    /**
+     * @return th_air_pressure
+     */
+    public Double getThAirPressure() {
+        return thAirPressure;
+    }
+
+    /**
+     * @param thAirPressure
+     */
+    public void setThAirPressure(Double thAirPressure) {
+        this.thAirPressure = thAirPressure;
+    }
+
+    /**
+     * @return th_engine_torque
+     */
+    public Double getThEngineTorque() {
+        return thEngineTorque;
+    }
+
+    /**
+     * @param thEngineTorque
+     */
+    public void setThEngineTorque(Double thEngineTorque) {
+        this.thEngineTorque = thEngineTorque;
+    }
+
+    /**
+     * @return th_friction_torque
+     */
+    public Double getThFrictionTorque() {
+        return thFrictionTorque;
+    }
+
+    /**
+     * @param thFrictionTorque
+     */
+    public void setThFrictionTorque(Double thFrictionTorque) {
+        this.thFrictionTorque = thFrictionTorque;
+    }
+
+    /**
+     * @return th_engine_rpm
+     */
+    public Integer getThEngineRpm() {
+        return thEngineRpm;
+    }
+
+    /**
+     * @param thEngineRpm
+     */
+    public void setThEngineRpm(Integer thEngineRpm) {
+        this.thEngineRpm = thEngineRpm;
+    }
+
+    /**
+     * @return th_start_fuel_flow
+     */
+    public Double getThStartFuelFlow() {
+        return thStartFuelFlow;
+    }
+
+    /**
+     * @param thStartFuelFlow
+     */
+    public void setThStartFuelFlow(Double thStartFuelFlow) {
+        this.thStartFuelFlow = thStartFuelFlow;
+    }
+
+    /**
+     * @return th_scr_upstream_NO
+     */
+    public Double getThScrUpstreamNo() {
+        return thScrUpstreamNo;
+    }
+
+    /**
+     * @param thScrUpstreamNo
+     */
+    public void setThScrUpstreamNo(Double thScrUpstreamNo) {
+        this.thScrUpstreamNo = thScrUpstreamNo;
+    }
+
+    /**
+     * @return th_scr_downstream_NO
+     */
+    public Double getThScrDownstreamNo() {
+        return thScrDownstreamNo;
+    }
+
+    /**
+     * @param thScrDownstreamNo
+     */
+    public void setThScrDownstreamNo(Double thScrDownstreamNo) {
+        this.thScrDownstreamNo = thScrDownstreamNo;
+    }
+
+    /**
+     * @return th_remain_reactant
+     */
+    public Double getThRemainReactant() {
+        return thRemainReactant;
+    }
+
+    /**
+     * @param thRemainReactant
+     */
+    public void setThRemainReactant(Double thRemainReactant) {
+        this.thRemainReactant = thRemainReactant;
+    }
+
+    /**
+     * @return th_air_input
+     */
+    public Double getThAirInput() {
+        return thAirInput;
+    }
+
+    /**
+     * @param thAirInput
+     */
+    public void setThAirInput(Double thAirInput) {
+        this.thAirInput = thAirInput;
+    }
+
+    /**
+     * @return th_scr_input_temp
+     */
+    public Double getThScrInputTemp() {
+        return thScrInputTemp;
+    }
+
+    /**
+     * @param thScrInputTemp
+     */
+    public void setThScrInputTemp(Double thScrInputTemp) {
+        this.thScrInputTemp = thScrInputTemp;
+    }
+
+    /**
+     * @return th_scr_output_temp
+     */
+    public Double getThScrOutputTemp() {
+        return thScrOutputTemp;
+    }
+
+    /**
+     * @param thScrOutputTemp
+     */
+    public void setThScrOutputTemp(Double thScrOutputTemp) {
+        this.thScrOutputTemp = thScrOutputTemp;
+    }
+
+    /**
+     * @return th_DPF
+     */
+    public Double getThDpf() {
+        return thDpf;
+    }
+
+    /**
+     * @param thDpf
+     */
+    public void setThDpf(Double thDpf) {
+        this.thDpf = thDpf;
+    }
+
+    /**
+     * @return th_engine_coolant_temp
+     */
+    public Double getThEngineCoolantTemp() {
+        return thEngineCoolantTemp;
+    }
+
+    /**
+     * @param thEngineCoolantTemp
+     */
+    public void setThEngineCoolantTemp(Double thEngineCoolantTemp) {
+        this.thEngineCoolantTemp = thEngineCoolantTemp;
+    }
+
+    /**
+     * @return th_fuel_level
+     */
+    public Double getThFuelLevel() {
+        return thFuelLevel;
+    }
+
+    /**
+     * @param thFuelLevel
+     */
+    public void setThFuelLevel(Double thFuelLevel) {
+        this.thFuelLevel = thFuelLevel;
+    }
+
+    /**
+     * @return th_location_status
+     */
+    public Integer getThLocationStatus() {
+        return thLocationStatus;
+    }
+
+    /**
+     * @param thLocationStatus
+     */
+    public void setThLocationStatus(Integer thLocationStatus) {
+        this.thLocationStatus = thLocationStatus;
+    }
+
+    /**
+     * @return th_total_mileage
+     */
+    public Double getThTotalMileage() {
+        return thTotalMileage;
+    }
+
+    /**
+     * @param thTotalMileage
+     */
+    public void setThTotalMileage(Double thTotalMileage) {
+        this.thTotalMileage = thTotalMileage;
+    }
+
+    /**
+     * @return th_engine_torque_mode
+     */
+    public String getThEngineTorqueMode() {
+        return thEngineTorqueMode;
+    }
+
+    /**
+     * @param thEngineTorqueMode
+     */
+    public void setThEngineTorqueMode(String thEngineTorqueMode) {
+        this.thEngineTorqueMode = thEngineTorqueMode == null ? null : thEngineTorqueMode.trim();
+    }
+
+    /**
+     * @return th_accelerator_pedal
+     */
+    public Double getThAcceleratorPedal() {
+        return thAcceleratorPedal;
+    }
+
+    /**
+     * @param thAcceleratorPedal
+     */
+    public void setThAcceleratorPedal(Double thAcceleratorPedal) {
+        this.thAcceleratorPedal = thAcceleratorPedal;
+    }
+
+    /**
+     * @return th_total_oil_consumption
+     */
+    public Double getThTotalOilConsumption() {
+        return thTotalOilConsumption;
+    }
+
+    /**
+     * @param thTotalOilConsumption
+     */
+    public void setThTotalOilConsumption(Double thTotalOilConsumption) {
+        this.thTotalOilConsumption = thTotalOilConsumption;
+    }
+
+    /**
+     * @return th_urea_box_temp
+     */
+    public Double getThUreaBoxTemp() {
+        return thUreaBoxTemp;
+    }
+
+    /**
+     * @param thUreaBoxTemp
+     */
+    public void setThUreaBoxTemp(Double thUreaBoxTemp) {
+        this.thUreaBoxTemp = thUreaBoxTemp;
+    }
+
+    /**
+     * @return th_urea_volume
+     */
+    public Integer getThUreaVolume() {
+        return thUreaVolume;
+    }
+
+    /**
+     * @param thUreaVolume
+     */
+    public void setThUreaVolume(Integer thUreaVolume) {
+        this.thUreaVolume = thUreaVolume;
+    }
+
+    /**
+     * @return th_total_urea_consume
+     */
+    public Double getThTotalUreaConsume() {
+        return thTotalUreaConsume;
+    }
+
+    /**
+     * @param thTotalUreaConsume
+     */
+    public void setThTotalUreaConsume(Double thTotalUreaConsume) {
+        this.thTotalUreaConsume = thTotalUreaConsume;
+    }
+
+    /**
+     * @return th_DPF_temp
+     */
+    public Double getThDpfTemp() {
+        return thDpfTemp;
+    }
+
+    /**
+     * @param thDpfTemp
+     */
+    public void setThDpfTemp(Double thDpfTemp) {
+        this.thDpfTemp = thDpfTemp;
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/VehicleInfo.java b/src/main/kotlin/com/flightfeather/uav/domain/entity/VehicleInfo.java
new file mode 100644
index 0000000..8969e7f
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/entity/VehicleInfo.java
@@ -0,0 +1,98 @@
+package com.flightfeather.uav.domain.entity;
+
+import javax.persistence.*;
+
+@Table(name = "obd_vehicle_info")
+public class VehicleInfo {
+    @Id
+    private Integer id;
+
+    @Column(name = "obd_device_code")
+    private String obdDeviceCode;
+
+    @Column(name = "obd_vin")
+    private String obdVin;
+
+    @Column(name = "obd_licence_plate")
+    private String obdLicencePlate;
+
+    /**
+     * 0: 闆嗗崱锛� 1锛氭福鍦熻溅
+     */
+    @Column(name = "obd_vehicle_type")
+    private Integer obdVehicleType;
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * @return obd_device_code
+     */
+    public String getObdDeviceCode() {
+        return obdDeviceCode;
+    }
+
+    /**
+     * @param obdDeviceCode
+     */
+    public void setObdDeviceCode(String obdDeviceCode) {
+        this.obdDeviceCode = obdDeviceCode == null ? null : obdDeviceCode.trim();
+    }
+
+    /**
+     * @return obd_vin
+     */
+    public String getObdVin() {
+        return obdVin;
+    }
+
+    /**
+     * @param obdVin
+     */
+    public void setObdVin(String obdVin) {
+        this.obdVin = obdVin == null ? null : obdVin.trim();
+    }
+
+    /**
+     * @return obd_licence_plate
+     */
+    public String getObdLicencePlate() {
+        return obdLicencePlate;
+    }
+
+    /**
+     * @param obdLicencePlate
+     */
+    public void setObdLicencePlate(String obdLicencePlate) {
+        this.obdLicencePlate = obdLicencePlate == null ? null : obdLicencePlate.trim();
+    }
+
+    /**
+     * 鑾峰彇1: 闆嗗崱锛� 2锛氭福鍦熻溅
+     *
+     * @return obd_vehicle_type - 1: 闆嗗崱锛� 2锛氭福鍦熻溅
+     */
+    public Integer getObdVehicleType() {
+        return obdVehicleType;
+    }
+
+    /**
+     * 璁剧疆1: 闆嗗崱锛� 2锛氭福鍦熻溅
+     *
+     * @param obdVehicleType 1: 闆嗗崱锛� 2锛氭福鍦熻溅
+     */
+    public void setObdVehicleType(Integer obdVehicleType) {
+        this.obdVehicleType = obdVehicleType;
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/mapper/AlarmDataMapper.kt b/src/main/kotlin/com/flightfeather/uav/domain/mapper/AlarmDataMapper.kt
new file mode 100644
index 0000000..ca3242e
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/mapper/AlarmDataMapper.kt
@@ -0,0 +1,8 @@
+package com.flightfeather.uav.domain.mapper
+
+import com.flightfeather.uav.domain.MyMapper
+import com.flightfeather.uav.domain.entity.AlarmData
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface AlarmDataMapper : MyMapper<AlarmData>
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/mapper/CarLoginMapper.kt b/src/main/kotlin/com/flightfeather/uav/domain/mapper/CarLoginMapper.kt
new file mode 100644
index 0000000..a45152b
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/mapper/CarLoginMapper.kt
@@ -0,0 +1,8 @@
+package com.flightfeather.uav.domain.mapper
+
+import com.flightfeather.uav.domain.MyMapper
+import com.flightfeather.uav.domain.entity.CarLogin
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface CarLoginMapper : MyMapper<CarLogin>
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/mapper/CarLogoutMapper.kt b/src/main/kotlin/com/flightfeather/uav/domain/mapper/CarLogoutMapper.kt
new file mode 100644
index 0000000..f594a22
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/mapper/CarLogoutMapper.kt
@@ -0,0 +1,8 @@
+package com.flightfeather.uav.domain.mapper
+
+import com.flightfeather.uav.domain.MyMapper
+import com.flightfeather.uav.domain.entity.CarLogout
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface CarLogoutMapper : MyMapper<CarLogout>
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/mapper/DataStreamMapper.kt b/src/main/kotlin/com/flightfeather/uav/domain/mapper/DataStreamMapper.kt
new file mode 100644
index 0000000..29c06f0
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/mapper/DataStreamMapper.kt
@@ -0,0 +1,8 @@
+package com.flightfeather.uav.domain.mapper
+
+import com.flightfeather.uav.domain.MyMapper
+import com.flightfeather.uav.domain.entity.DataStream
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface DataStreamMapper : MyMapper<DataStream>
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/mapper/ObdDataMapper.kt b/src/main/kotlin/com/flightfeather/uav/domain/mapper/ObdDataMapper.kt
new file mode 100644
index 0000000..bd6bf26
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/mapper/ObdDataMapper.kt
@@ -0,0 +1,8 @@
+package com.flightfeather.uav.domain.mapper
+
+import com.flightfeather.uav.domain.MyMapper
+import com.flightfeather.uav.domain.entity.ObdData
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface ObdDataMapper : MyMapper<ObdData>
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/mapper/ObdInfoMapper.kt b/src/main/kotlin/com/flightfeather/uav/domain/mapper/ObdInfoMapper.kt
new file mode 100644
index 0000000..2f50397
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/mapper/ObdInfoMapper.kt
@@ -0,0 +1,8 @@
+package com.flightfeather.uav.domain.mapper
+
+import com.flightfeather.uav.domain.MyMapper
+import com.flightfeather.uav.domain.entity.ObdInfo
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface ObdInfoMapper : MyMapper<ObdInfo>
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/mapper/ObdUserMapper.kt b/src/main/kotlin/com/flightfeather/uav/domain/mapper/ObdUserMapper.kt
new file mode 100644
index 0000000..2f6bf1a
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/mapper/ObdUserMapper.kt
@@ -0,0 +1,8 @@
+package com.flightfeather.uav.domain.mapper
+
+import com.flightfeather.uav.domain.MyMapper
+import com.flightfeather.uav.domain.entity.ObdUser
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface ObdUserMapper : MyMapper<ObdUser>
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/mapper/OriginDataMapper.kt b/src/main/kotlin/com/flightfeather/uav/domain/mapper/OriginDataMapper.kt
new file mode 100644
index 0000000..dd95e02
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/mapper/OriginDataMapper.kt
@@ -0,0 +1,8 @@
+package com.flightfeather.uav.domain.mapper
+
+import com.flightfeather.uav.domain.MyMapper
+import com.flightfeather.uav.domain.entity.OriginData
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface OriginDataMapper : MyMapper<OriginData>
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/mapper/ThresholdValueMapper.kt b/src/main/kotlin/com/flightfeather/uav/domain/mapper/ThresholdValueMapper.kt
new file mode 100644
index 0000000..7626536
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/mapper/ThresholdValueMapper.kt
@@ -0,0 +1,8 @@
+package com.flightfeather.uav.domain.mapper
+
+import com.flightfeather.uav.domain.MyMapper
+import com.flightfeather.uav.domain.entity.ThresholdValue
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface ThresholdValueMapper : MyMapper<ThresholdValue>
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/mapper/VehicleInfoMapper.kt b/src/main/kotlin/com/flightfeather/uav/domain/mapper/VehicleInfoMapper.kt
new file mode 100644
index 0000000..df9b1c7
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/domain/mapper/VehicleInfoMapper.kt
@@ -0,0 +1,8 @@
+package com.flightfeather.uav.domain.mapper
+
+import com.flightfeather.uav.domain.MyMapper
+import com.flightfeather.uav.domain.entity.VehicleInfo
+import org.apache.ibatis.annotations.Mapper
+
+@Mapper
+interface VehicleInfoMapper : MyMapper<VehicleInfo>
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/bean/AlarmDataVo.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/AlarmDataVo.kt
new file mode 100644
index 0000000..6abfb2b
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/AlarmDataVo.kt
@@ -0,0 +1,46 @@
+package com.flightfeather.uav.lightshare.bean
+
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/2
+ */
+class AlarmDataVo :BaseJson() {
+    var id: Int? = null
+    var obdVin: String? = null
+    var alarmTime: Date? = null
+    var alarmLng: Double? = null
+    var alarmLat: Double? = null
+    var alarmProtocol: Int? = null
+    var alarmMil: Int? = null
+    var alarmIdCode: String? = null
+    var alarmVerificationCode: String? = null
+    var alarmFaultCodeNum: Int? = null
+    var alarmFaultCode: String? = null
+    var alarmSpeed: Int? = null
+    var alarmAirPressure: Double? = null
+    var alarmEngineTorque: Double? = null
+    var alarmFrictionTorque: Double? = null
+    var alarmEngineRpm: Int? = null
+    var alarmStartFuelFlow: Double? = null
+    var alarmScrUpstreamNo: Double? = null
+    var alarmScrDownstreamNo: Double? = null
+    var alarmRemainReactant: Double? = null
+    var alarmAirInput: Double? = null
+    var alarmScrInputTemp: Double? = null
+    var alarmScrOutputTemp: Double? = null
+    var alarmDpf: Double? = null
+    var alarmEngineCoolantTemp: Double? = null
+    var alarmFuelLevel: Double? = null
+    var alarmLocationStatus: Int? = null
+    var alarmTotalMileage: Double? = null
+    var alarmEngineTorqueMode: String? = null
+    var alarmAcceleratorPedal: Double? = null
+    var alarmTotalOilConsumption: Double? = null
+    var alarmUreaBoxTemp: Double? = null
+    var alarmUreaVolume: Int? = null
+    var alarmTotalUreaConsume: Double? = null
+    var alarmDpfTemp: Double? = null
+    var alarmFirmwareVersion: String? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/bean/BaseJson.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/BaseJson.kt
new file mode 100644
index 0000000..c8bdae3
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/BaseJson.kt
@@ -0,0 +1,15 @@
+package com.flightfeather.uav.lightshare.bean
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties
+import com.fasterxml.jackson.annotation.JsonInclude
+
+/**
+ * 鍩虹Json缁撴瀯锛屾墍鏈夌殑鏁版嵁浠ユ涓哄熀绫�
+ * @author riku
+ * Date: 2019/8/27
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+open class BaseJson{
+    val cmdCode: Int? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/bean/CarLoginVo.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/CarLoginVo.kt
new file mode 100644
index 0000000..91917d8
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/CarLoginVo.kt
@@ -0,0 +1,16 @@
+package com.flightfeather.uav.lightshare.bean
+
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/19
+ */
+class CarLoginVo : BaseJson() {
+    var id: Int? = null
+    var obdDeviceCode: String? = null
+    var loginCreateTime: Date? = null
+    var loginDataTime: Date? = null
+    var loginSerialNum: Int? = null
+    var loginSimCode: String? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/bean/CarLogoutVo.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/CarLogoutVo.kt
new file mode 100644
index 0000000..1a3cbf7
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/CarLogoutVo.kt
@@ -0,0 +1,15 @@
+package com.flightfeather.uav.lightshare.bean
+
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/19
+ */
+class CarLogoutVo : BaseJson() {
+    var id: Int? = null
+    var obdDeviceCode: String? = null
+    var loginCreateTime: Date? = null
+    var loginDataTime: Date? = null
+    var loginSerialNum: Int? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/bean/DataStreamVo.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/DataStreamVo.kt
new file mode 100644
index 0000000..cd5308f
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/DataStreamVo.kt
@@ -0,0 +1,42 @@
+package com.flightfeather.uav.lightshare.bean
+
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/19
+ */
+class DataStreamVo : BaseJson() {
+    var id: Int?= null
+    var obdDeviceCode: String?= null
+    var obdCreateTime: Date?= null
+    var obdDataTime: Date?= null
+    var obdSerialNum: Int?= null
+    var obdSpeed: Double?= null
+    var obdAirPressure: Double?= null
+    var obdEngineTorque: Double?= null
+    var obdFrictionTorque: Double?= null
+    var obdEngineRpm: Double?= null
+    var obdEngineFuelFlow: Double?= null
+    var obdScrUpstreamNox: Double?= null
+    var obdScrDownstreamNox: Double?= null
+    var obdRemainReactant: Double?= null
+    var obdAirInput: Double?= null
+    var obdScrInputTemp: Double?= null
+    var obdScrOutputTemp: Double?= null
+    var obdDpf: Double?= null
+    var obdEngineCoolantTemp: Double?= null
+    var obdFuelLevel: Double?= null
+    var obdLocationStatus: String?= null
+    var obdLong: Double?= null
+    var obdLat: Double?= null
+    var obdTotalMileage: Double?= null
+    var obdEngineTorqueMode: Int?= null
+    var obdAcceleratorPedal: Double?= null
+    var obdTotalOilConsumption: Double?= null
+    var obdUreaBoxTemp: Double?= null
+    var obdUreaVolume: Double?= null
+    var obdTotalUreaConsume: Double?= null
+    var obdDpfTemp: Double?= null
+    var obdStatus: Boolean?= null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/bean/LatLngVo.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/LatLngVo.kt
new file mode 100644
index 0000000..33ab5f5
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/LatLngVo.kt
@@ -0,0 +1,20 @@
+package com.flightfeather.uav.lightshare.bean
+
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/19
+ */
+class LatLngVo : BaseJson() {
+    var deviceCode: String? = null
+    var vin: String? = null
+    var license: String? = null
+    var obdDataTime: Date? = null
+    //杞﹁締绫诲瀷
+    var carType: Int? = null
+    //杞﹁締鐘舵��
+    var status: Int = 0
+    var lat: Double? = null
+    var lng: Double? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/bean/ObdDataVo.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/ObdDataVo.kt
new file mode 100644
index 0000000..7f41288
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/ObdDataVo.kt
@@ -0,0 +1,45 @@
+package com.flightfeather.uav.lightshare.bean
+
+import com.google.gson.annotations.SerializedName
+import java.util.*
+
+class ObdDataVo :  BaseJson() {
+    var id: Int? = null
+    @SerializedName("vin")
+    var obdVin: String? = null
+    var obdTime: Date? = null
+    var obdLng: Double? = null
+    var obdLat: Double? = null
+    @SerializedName("protocol")
+    var obdProtocol: Int? = null
+    var obdMil: Int? = null
+    var obdIdCode: String? = null
+    var obdVerificationCode: String? = null
+    var obdFaultCodeNum: Int? = null
+    var obdFaultCode: String? = null
+    var obdSpeed: Int? = null
+    var obdAirPressure: Double? = null
+    var obdEngineTorque: Double? = null
+    var obdFrictionTorque: Double? = null
+    var obdEngineRpm: Int? = null
+    var obdEngineFuelFlow: Double? = null
+    var obdScrUpstreamNo: Double? = null
+    var obdScrDownstreamNo: Double? = null
+    var obdRemainReactant: Double? = null
+    var obdAirInput: Double? = null
+    var obdScrInputTemp: Double? = null
+    var obdScrOutputTemp: Double? = null
+    var obdDpf: Double? = null
+    var obdEngineCoolantTemp: Double? = null
+    var obdFuelLevel: Double? = null
+    var obdLocationStatus: Int? = null
+    var obdTotalMileage: Double? = null
+    var obdEngineTorqueMode: String? = null
+    var obdAcceleratorPedal: Double? = null
+    var obdTotalOilConsumption: Double? = null
+    var obdUreaBoxTemp: Double? = null
+    var obdUreaVolume: Int? = null
+    var obdTotalUreaConsume: Double? = null
+    var obdDpfTemp: Double? = null
+    var obdFirmwareVersion: String? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/bean/ObdInfoVo.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/ObdInfoVo.kt
new file mode 100644
index 0000000..7ab46a6
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/ObdInfoVo.kt
@@ -0,0 +1,26 @@
+package com.flightfeather.uav.lightshare.bean
+
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/19
+ */
+class ObdInfoVo : BaseJson() {
+    var id: Int?= null
+    var obdDeviceCode: String?= null
+    var obdCreateTime: Date?= null
+    var obdDataTime: Date?= null
+    var obdSerialNum: Int?= null
+    var obdProtocol: Int?= null
+    var obdMil: Int?= null
+    var obdDiagnosisSupportStatus: String?= null
+    var obdDiagnosisReadyStatus: String?= null
+    var obdVin: String?= null
+    var obdCrn: String?= null
+    var obdCvn: String?= null
+    var obdIupr: String?= null
+    var obdFaultCodeNum: Int?= null
+    var obdFaultCode: String?= null
+    var obdStatus: Boolean?= null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/bean/ObdUserVo.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/ObdUserVo.kt
new file mode 100644
index 0000000..0461c78
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/ObdUserVo.kt
@@ -0,0 +1,13 @@
+package com.flightfeather.uav.lightshare.bean
+
+
+/**
+ * @author riku
+ * Date: 2019/9/2
+ */
+class ObdUserVo : BaseJson() {
+    var id: Int? = null
+    var obdVin: String? = null
+    var obdUserId: Double? = null
+    var obdUserName: String? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/bean/ThresholdValueVo.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/ThresholdValueVo.kt
new file mode 100644
index 0000000..44d25a4
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/ThresholdValueVo.kt
@@ -0,0 +1,37 @@
+package com.flightfeather.uav.lightshare.bean
+
+/**
+ * @author riku
+ * Date: 2019/9/2
+ */
+class ThresholdValueVo : BaseJson() {
+    var id:Int? = null
+    var obdVin:String? = null
+    var thMil:Int? = null
+    var thFaultCodeNum:Int? = null
+    var thFaultCode:String? = null
+    var thSpeed:Int? = null
+    var thAirPressure:Double? = null
+    var thEngineTorque:Double? = null
+    var thFrictionTorque:Double? = null
+    var thEngineRpm:Int? = null
+    var thStartFuelFlow:Double? = null
+    var thScrUpstreamNo:Double? = null
+    var thScrDownstreamNo:Double? = null
+    var thRemainReactant:Double? = null
+    var thAirInput:Double? = null
+    var thScrInputTemp:Double? = null
+    var thScrOutputTemp:Double? = null
+    var thDpf:Double? = null
+    var thEngineCoolantTemp:Double? = null
+    var thFuelLevel:Double? = null
+    var thLocationStatus:Int? = null
+    var thTotalMileage:Double? = null
+    var thEngineTorqueMode:String? = null
+    var thAcceleratorPedal:Double? = null
+    var thTotalOilConsumption:Double? = null
+    var thUreaBoxTemp:Double? = null
+    var thUreaVolume:Int? = null
+    var thTotalUreaConsume:Double? = null
+    var thDpfTemp:Double? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/bean/VehicleInfoVo.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/VehicleInfoVo.kt
new file mode 100644
index 0000000..8cf166e
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/bean/VehicleInfoVo.kt
@@ -0,0 +1,20 @@
+package com.flightfeather.uav.lightshare.bean
+
+/**
+ * @author riku
+ * Date: 2019/10/25
+ */
+class VehicleInfoVo : BaseJson() {
+    var id: Int? = null
+
+    var obdDeviceCode: String? = null
+
+    var obdVin: String? = null
+
+    var obdLicencePlate: String? = null
+
+    /**
+     * 0: 闆嗗崱锛� 1锛氭福鍦熻溅
+     */
+    var obdVehicleType: Int? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/eunm/CarStatus.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/eunm/CarStatus.kt
new file mode 100644
index 0000000..53f6201
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/eunm/CarStatus.kt
@@ -0,0 +1,17 @@
+package com.flightfeather.uav.lightshare.eunm
+
+/**
+ * @author riku
+ * Date: 2019/9/26
+ * 杞﹁締鐘舵��
+ * 0锛氱绾�
+ * 1锛氬湪绾�
+ * 2锛氳鎶�
+ * 3锛氳秴鏍�
+ */
+enum class CarStatus(val value: Int) {
+    OffLine(0),
+    OnLine(1),
+    Warn(2),
+    Exceed(3)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/eunm/CarType.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/eunm/CarType.kt
new file mode 100644
index 0000000..51854d1
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/eunm/CarType.kt
@@ -0,0 +1,12 @@
+package com.flightfeather.uav.lightshare.eunm
+
+/**
+ * @author riku
+ * Date: 2019/9/26
+ */
+enum class CarType(val value: Int){
+    //闆嗚绠卞崱杞�
+    ContainerTruck(0),
+    //娓e湡杞�
+    SlagCar(1)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdAlarmService.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdAlarmService.kt
new file mode 100644
index 0000000..70c794a
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdAlarmService.kt
@@ -0,0 +1,16 @@
+package com.flightfeather.uav.lightshare.service
+
+import com.flightfeather.uav.lightshare.bean.AlarmDataVo
+
+/**
+ * @author riku
+ * Date: 2019/9/5
+ */
+interface ObdAlarmService {
+
+    /**
+     * 鏍规嵁vin鐮佽幏鍙栬鎶ユ暟鎹�
+     */
+    fun getAlarmByVinCode(vinCode: String, pageNum: Int?, pageSize: Int?): MutableList<AlarmDataVo>
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdDataService.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdDataService.kt
new file mode 100644
index 0000000..3faf50f
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdDataService.kt
@@ -0,0 +1,60 @@
+package com.flightfeather.uav.lightshare.service
+
+import com.flightfeather.uav.lightshare.bean.*
+
+/**
+ * @author riku
+ * Date: 2019/8/27
+ */
+interface ObdDataService {
+
+    /**
+     * 鏍规嵁vin鐮佽幏鍙栧搴旀暟鎹�
+     */
+    fun getDataByVinCode(vinCode: String?, pageNum: Int?, pageSize: Int?): MutableList<ObdDataVo>
+
+    /**
+     * 鏍规嵁缁堢璁惧鐮佽幏鍙栫櫥褰曟暟鎹�
+     */
+    fun getLoginData(deviceCode: String, pageNum: Int?, pageSize: Int?, startTime: String?, endTime: String?): List<CarLoginVo>
+
+    /**
+     * 鏍规嵁缁堢璁惧鐮佽幏鍙栫櫥鍑烘暟鎹�
+     */
+    fun getLogoutData(deviceCode: String, pageNum: Int?, pageSize: Int?, startTime: String?, endTime: String?): List<CarLogoutVo>
+
+    /**
+     * 鏍规嵁缁堢璁惧鐮佽幏鍙杘bd鏁版嵁
+     */
+    fun getObdInfo(deviceCode: String, pageNum: Int?, pageSize: Int?): List<ObdInfoVo>
+
+    /**
+     * 鏍规嵁缁堢璁惧鐮佽幏鍙栨暟鎹祦鏁版嵁
+     */
+    fun getDataStream(deviceCode: String, pageNum: Int?, pageSize: Int?, startTime: String?, endTime: String?): List<DataStreamVo>
+
+    /**
+     * 鏍规嵁缁堢璁惧鐮佽幏鍙栨暟鎹祦鏁版嵁璁℃暟
+     */
+    fun getDataStreamCount(deviceCode: String, startTime: String?, endTime: String?): Int
+
+    /**
+     * 鏍规嵁缁堢璁惧鐮佽幏鍙栨渶鏂扮粡绾害
+     */
+    fun getCoordinate(deviceCode: String): LatLngVo
+
+    /**
+     * 鏍规嵁缁堢璁惧鐮佷互鍙婃椂闀縯 鑾峰彇t涔嬪墠鍒扮幇鍦ㄧ殑鎵�鏈夎建杩瑰潗鏍�
+     */
+    fun getTrack(deviceCode: String, startTime: String, endTime: String): List<LatLngVo>
+
+    /**
+     * 鑾峰彇鏈�鏂扮殑杞﹁締鍧愭爣淇℃伅
+     */
+    fun getLatestCoordinate(pageNum: Int?, pageSize: Int?): List<LatLngVo>
+
+    /**
+     * 鏍规嵁缁堢璁惧鐮佸強鏃堕棿娈碉紝缁欏嚭姝ゆ鏃堕棿鍐呯殑鍧愭爣
+     */
+    //TODO
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdThresholdValueService.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdThresholdValueService.kt
new file mode 100644
index 0000000..9366a45
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdThresholdValueService.kt
@@ -0,0 +1,26 @@
+package com.flightfeather.uav.lightshare.service
+
+import com.flightfeather.uav.lightshare.bean.ThresholdValueVo
+
+/**
+ * @author riku
+ * Date: 2019/9/5
+ */
+interface ObdThresholdValueService {
+
+    /**
+     * 淇濆瓨
+     */
+    fun save(userId: String, thresholdValueVo: ThresholdValueVo): Boolean
+
+    /**
+     * 鏇存柊
+     */
+    fun update(userId: String, thresholdValueVo: ThresholdValueVo): Boolean
+
+    /**
+     * 鏍规嵁vin鐮佽幏鍙栧搴旈槇鍊�
+     */
+    fun getDataByVinCode(vinCode: String): ThresholdValueVo?
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdUserService.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdUserService.kt
new file mode 100644
index 0000000..261dd26
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/ObdUserService.kt
@@ -0,0 +1,13 @@
+package com.flightfeather.uav.lightshare.service
+
+import com.flightfeather.uav.lightshare.bean.ObdUserVo
+
+/**
+ * @author riku
+ * Date: 2019/9/6
+ */
+interface ObdUserService {
+
+    fun getUserInfo(userId: String): ObdUserVo?
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/VehicleService.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/VehicleService.kt
new file mode 100644
index 0000000..53753f5
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/VehicleService.kt
@@ -0,0 +1,17 @@
+package com.flightfeather.uav.lightshare.service
+
+import com.flightfeather.uav.lightshare.bean.VehicleInfoVo
+
+/**
+ * @author riku
+ * Date: 2019/10/25
+ * 杞﹁締鐩稿叧淇℃伅鎺ュ彛
+ */
+interface VehicleService {
+
+    /**
+     * 鑾峰彇杞﹁締淇℃伅
+     */
+    fun getVehicleInfo(pageNum: Int?, pageSize: Int?): List<VehicleInfoVo>
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdAlarmServiceImpl.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdAlarmServiceImpl.kt
new file mode 100644
index 0000000..9cd9de3
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdAlarmServiceImpl.kt
@@ -0,0 +1,19 @@
+package com.flightfeather.uav.lightshare.service.impl
+
+import com.flightfeather.uav.lightshare.bean.AlarmDataVo
+import com.flightfeather.uav.lightshare.service.ObdAlarmService
+import com.flightfeather.uav.repository.ObdAlarmRepository
+import org.springframework.stereotype.Service
+
+/**
+ * @author riku
+ * Date: 2019/9/5
+ */
+@Service
+class ObdAlarmServiceImpl(val obdAlarmRepository: ObdAlarmRepository) : ObdAlarmService {
+
+    override fun getAlarmByVinCode(vinCode: String, pageNum: Int?, pageSize: Int?): MutableList<AlarmDataVo> {
+        return obdAlarmRepository.getAlarmByVinCode(vinCode, pageNum, pageSize)
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdDataServiceImpl.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdDataServiceImpl.kt
new file mode 100644
index 0000000..6bf01cf
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdDataServiceImpl.kt
@@ -0,0 +1,164 @@
+package com.flightfeather.uav.lightshare.service.impl
+
+import com.flightfeather.uav.lightshare.bean.*
+import com.flightfeather.uav.lightshare.eunm.CarStatus
+import com.flightfeather.uav.lightshare.service.ObdDataService
+import com.flightfeather.uav.repository.*
+import org.springframework.beans.BeanUtils
+import org.springframework.stereotype.Service
+import java.time.LocalDateTime
+import java.time.ZoneId
+
+/**
+ * @author riku
+ * Date: 2019/8/27
+ */
+@Service
+class ObdDataServiceImpl(
+        val obdDataRepository: ObdDataRepository,
+        val carLoginRepository: CarLoginRepository,
+        val carLogoutRepository: CarLogoutRepository,
+        val obdInfoRepository: ObdInfoRepository,
+        val dataStreamRepository: DataStreamRepository,
+        val vehicleRepository: VehicleRepository
+) : ObdDataService {
+
+    override fun getDataByVinCode(vinCode: String?, pageNum: Int?, pageSize: Int?): MutableList<ObdDataVo>{
+        val resultList = mutableListOf<ObdDataVo>()
+
+        vehicleRepository.getVehicleInfo(pageNum, pageSize).forEach { vehicleInfo ->
+            val dataStream = dataStreamRepository.getLatestDataStream(vehicleInfo.obdDeviceCode)
+            val obdInfo = obdInfoRepository.getObdInfo(vehicleInfo.obdDeviceCode, 1, 1).takeIf { it.isNotEmpty() }?.get(0)
+
+            resultList.add(ObdDataVo().apply {
+                obdVin = obdInfo?.obdDeviceCode
+                obdTime = dataStream?.obdDataTime
+                obdLng = dataStream?.obdLong
+                obdLat = dataStream?.obdLat
+                obdProtocol = obdInfo?.obdProtocol
+                obdMil = obdInfo?.obdMil
+//                obdIdCode
+//                obdVerificationCode
+                obdFaultCodeNum = obdInfo?.obdFaultCodeNum
+                obdFaultCode = obdInfo?.obdFaultCode
+                obdSpeed = dataStream?.obdSpeed?.toInt()
+                obdAirPressure = dataStream?.obdAirPressure
+                obdEngineTorque = dataStream?.obdEngineTorque
+                obdFrictionTorque = dataStream?.obdFrictionTorque
+                obdEngineRpm = dataStream?.obdEngineRpm?.toInt()
+                obdEngineFuelFlow = dataStream?.obdEngineFuelFlow
+                obdScrUpstreamNo = dataStream?.obdScrUpstreamNox
+                obdScrDownstreamNo = dataStream?.obdScrDownstreamNox
+                obdRemainReactant = dataStream?.obdRemainReactant
+                obdAirInput = dataStream?.obdAirInput
+                obdScrInputTemp = dataStream?.obdScrInputTemp
+                obdScrOutputTemp = dataStream?.obdScrOutputTemp
+                obdDpf = dataStream?.obdDpf
+                obdEngineCoolantTemp = dataStream?.obdEngineCoolantTemp
+                obdFuelLevel = dataStream?.obdFuelLevel
+//                obdLocationStatus = dataStream?.obdLocationStatus
+                obdTotalMileage = dataStream?.obdTotalMileage
+                obdEngineTorqueMode = dataStream?.obdEngineTorqueMode?.toString()
+                obdAcceleratorPedal = dataStream?.obdAcceleratorPedal
+                obdTotalOilConsumption = dataStream?.obdTotalOilConsumption
+                obdUreaBoxTemp = dataStream?.obdUreaBoxTemp
+                obdUreaVolume = dataStream?.obdUreaVolume?.toInt()
+                obdTotalUreaConsume = dataStream?.obdTotalUreaConsume
+                obdDpfTemp = dataStream?.obdDpfTemp
+//                obdFirmwareVersion = dataStream?.
+            })
+        }
+
+        return resultList
+    }
+
+    override fun getLoginData(deviceCode: String, pageNum: Int?, pageSize: Int?, startTime: String?, endTime: String?): List<CarLoginVo>
+            = carLoginRepository.getLoginData(deviceCode, pageNum, pageSize, startTime, endTime)
+
+    override fun getLogoutData(deviceCode: String, pageNum: Int?, pageSize: Int?, startTime: String?, endTime: String?): List<CarLogoutVo>
+            = carLogoutRepository.getLogoutData(deviceCode, pageNum, pageSize, startTime, endTime)
+
+    override fun getObdInfo(deviceCode: String, pageNum: Int?, pageSize: Int?): List<ObdInfoVo>{
+        val resultList = mutableListOf<ObdInfoVo>()
+        obdInfoRepository.getObdInfo(deviceCode, pageNum, pageSize).forEach {
+            val vo = ObdInfoVo()
+            BeanUtils.copyProperties(it, vo)
+            resultList.add(vo)
+        }
+        return resultList
+    }
+
+    override fun getDataStream(deviceCode: String, pageNum: Int?, pageSize: Int?, startTime: String?, endTime: String?): List<DataStreamVo>
+            = dataStreamRepository.getDataStream(deviceCode, pageNum, pageSize, startTime, endTime)
+
+    override fun getDataStreamCount(deviceCode: String, startTime: String?, endTime: String?): Int
+            = dataStreamRepository.getDataStreamCount(deviceCode, startTime, endTime)
+
+    override fun getCoordinate(deviceCode: String): LatLngVo{
+        val latLngVo = LatLngVo()
+        dataStreamRepository.getLatestDataStream(deviceCode)?.let {
+            latLngVo.apply {
+                this.deviceCode = it.obdDeviceCode
+                obdDataTime = it.obdDataTime
+                lat = it.obdLat
+                lng = it.obdLong
+            }
+        }
+
+        return latLngVo
+    }
+
+    override fun getTrack(deviceCode: String, startTime: String, endTime: String): List<LatLngVo> {
+        val resultList = mutableListOf<LatLngVo>()
+        //2019.10.30 鐩墠鍓嶇瀹夊崜璁惧畾鏈�闀胯幏鍙栫殑鏃堕暱涓�6灏忔椂鍓嶈嚦鐜板湪鐨勬暟鎹紝鎸夌収obd 姣�10绉掍腑浜х敓涓�鏉℃暟鎹紝鏈�澶�4 * 360 = 1440 鏉�
+        dataStreamRepository.getDataStream(deviceCode, 1, 1500, startTime, endTime).run {
+            sortedBy {
+                it.obdDataTime
+            }
+        }.forEach {
+            val latLngVo = LatLngVo().apply {
+                this.deviceCode = it.obdDeviceCode
+                obdDataTime = it.obdDataTime
+                lat = it.obdLat
+                lng = it.obdLong
+            }
+            resultList.add(latLngVo)
+        }
+        return resultList
+    }
+
+    override fun getLatestCoordinate(pageNum: Int?, pageSize: Int?): List<LatLngVo> {
+        val resultList = mutableListOf<LatLngVo>()
+
+        val now = LocalDateTime.now()
+
+        vehicleRepository.getVehicleInfo(pageNum, pageSize).forEach { vehicleInfo ->
+            val dataStream = dataStreamRepository.getLatestDataStream(vehicleInfo.obdDeviceCode)
+            val obdInfo = obdInfoRepository.getObdInfo(vehicleInfo.obdDeviceCode, 1, 1).takeIf { it.isNotEmpty() }?.get(0)
+
+            //鑾峰彇鏁版嵁閲囨牱鏃堕棿锛屽鏋滀负绌猴紝鍒欏彇褰撳墠鏃堕棿鐨勫墠24灏忔椂
+            val dataTime = dataStream?.obdDataTime?.toInstant()?.atZone(ZoneId.systemDefault())?.toLocalDateTime()
+                    ?: LocalDateTime.now().minusDays(1)
+
+            resultList.add(LatLngVo().apply {
+                deviceCode = vehicleInfo.obdDeviceCode
+                vin = obdInfo?.obdVin
+                license = vehicleInfo.obdLicencePlate
+                obdDataTime = dataStream?.obdDataTime
+                carType = vehicleInfo.obdVehicleType
+                //閲囨牱鏃堕棿鍜屽綋鍓嶆椂闂寸浉宸秴杩�10鍒嗛挓璁や负璁惧澶勪簬绂荤嚎鐘舵��
+                //todo 2019.10.25 鍏朵綑涓ょ杞﹁締鐘舵�侊紝鍚庣画闇�澶勭悊
+                status = if (now.minusMinutes(10).isAfter(dataTime)) {
+                    CarStatus.OffLine.value
+                } else {
+                    CarStatus.OnLine.value
+                }
+                lat = dataStream?.obdLat
+                lng = dataStream?.obdLong
+            })
+        }
+
+        return resultList
+
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdThresholdValueServiceImpl.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdThresholdValueServiceImpl.kt
new file mode 100644
index 0000000..29ab32b
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdThresholdValueServiceImpl.kt
@@ -0,0 +1,27 @@
+package com.flightfeather.uav.lightshare.service.impl
+
+import com.flightfeather.uav.lightshare.bean.ThresholdValueVo
+import com.flightfeather.uav.lightshare.service.ObdThresholdValueService
+import com.flightfeather.uav.repository.ObdThresholdValueRepository
+import org.springframework.stereotype.Service
+
+/**
+ * @author riku
+ * Date: 2019/9/5
+ */
+@Service
+class ObdThresholdValueServiceImpl(val obdThresholdValueRepository: ObdThresholdValueRepository) : ObdThresholdValueService {
+
+    override fun save(userId: String, thresholdValueVo: ThresholdValueVo): Boolean {
+        return obdThresholdValueRepository.save(userId, thresholdValueVo)
+    }
+
+    override fun update(userId: String, thresholdValueVo: ThresholdValueVo): Boolean {
+        return obdThresholdValueRepository.update(userId, thresholdValueVo)
+    }
+
+    override fun getDataByVinCode(vinCode: String): ThresholdValueVo? {
+        return obdThresholdValueRepository.getByVinCode(vinCode)
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdUserServiceImpl.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdUserServiceImpl.kt
new file mode 100644
index 0000000..6c40d05
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/ObdUserServiceImpl.kt
@@ -0,0 +1,18 @@
+package com.flightfeather.uav.lightshare.service.impl
+
+import com.flightfeather.uav.lightshare.bean.ObdUserVo
+import com.flightfeather.uav.lightshare.service.ObdUserService
+import com.flightfeather.uav.repository.ObdUserRepository
+import org.springframework.stereotype.Service
+
+/**
+ * @author riku
+ * Date: 2019/9/6
+ */
+@Service
+class ObdUserServiceImpl(val userRepository: ObdUserRepository) :ObdUserService{
+
+    override fun getUserInfo(userId: String): ObdUserVo? {
+        return userRepository.getUserInfo(userId)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/VehicleServiceImpl.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/VehicleServiceImpl.kt
new file mode 100644
index 0000000..00c1d22
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/VehicleServiceImpl.kt
@@ -0,0 +1,28 @@
+package com.flightfeather.uav.lightshare.service.impl
+
+import com.flightfeather.uav.lightshare.bean.VehicleInfoVo
+import com.flightfeather.uav.lightshare.service.VehicleService
+import com.flightfeather.uav.repository.VehicleRepository
+import org.springframework.beans.BeanUtils
+import org.springframework.stereotype.Service
+
+/**
+ * @author riku
+ * Date: 2019/10/25
+ */
+@Service
+class VehicleServiceImpl(val vehicleRepository: VehicleRepository) : VehicleService {
+    override fun getVehicleInfo(pageNum: Int?, pageSize: Int?): List<VehicleInfoVo> {
+        val dbResult = vehicleRepository.getVehicleInfo(pageNum, pageSize)
+
+        val resultList = mutableListOf<VehicleInfoVo>()
+
+        dbResult.forEach {
+            val vo = VehicleInfoVo()
+            BeanUtils.copyProperties(it, vo)
+            resultList.add(vo)
+        }
+
+        return resultList
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdAlarmController.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdAlarmController.kt
new file mode 100644
index 0000000..418cf5b
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdAlarmController.kt
@@ -0,0 +1,21 @@
+package com.flightfeather.uav.lightshare.web
+
+import com.flightfeather.uav.lightshare.service.ObdAlarmService
+import org.springframework.web.bind.annotation.*
+
+/**
+ * @author riku
+ * Date: 2019/9/5
+ */
+@RestController
+@RequestMapping("uav/alarm")
+class ObdAlarmController(val obdAlarmService: ObdAlarmService) {
+
+    @GetMapping("/{vinCode}")
+    fun getAlarmByVinCode(
+            @PathVariable("vinCode") vinCode: String,
+            @RequestParam("page", required = false) pageNum: Int?,
+            @RequestParam("per_page", required = false) pageSize: Int?
+    ) = obdAlarmService.getAlarmByVinCode(vinCode, pageNum, pageSize)
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdDataController.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdDataController.kt
new file mode 100644
index 0000000..7b28cad
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdDataController.kt
@@ -0,0 +1,79 @@
+package com.flightfeather.uav.lightshare.web
+
+import com.flightfeather.uav.lightshare.service.ObdDataService
+import org.springframework.web.bind.annotation.*
+
+/**
+ * @author riku
+ * Date: 2019/8/27
+ */
+@RestController
+@RequestMapping("uav/data")
+class ObdDataController(val obdDataService: ObdDataService) {
+
+    @GetMapping("/data")
+    fun getById(
+            @RequestParam("vinCode", required = false) vinCode: String?,
+            @RequestParam("page", required = false) pageNum: Int?,
+            @RequestParam("per_page", required = false) pageSize: Int?
+    ) = obdDataService.getDataByVinCode(vinCode, pageNum, pageSize)
+
+    @GetMapping("/login/{deviceCode}")
+    fun getLoginData(
+            @PathVariable("deviceCode") deviceCode: String,
+            @RequestParam("page", required = false) pageNum: Int?,
+            @RequestParam("per_page", required = false) pageSize: Int?,
+            @RequestParam("startTime", required = false) startTime: String?,
+            @RequestParam("endTime", required = false) endTime: String?
+    ) = obdDataService.getLoginData(deviceCode, pageNum, pageSize, startTime, endTime)
+
+    @GetMapping("/logout/{deviceCode}")
+    fun getLogoutData(
+            @PathVariable("deviceCode") deviceCode: String,
+            @RequestParam("page", required = false) pageNum: Int?,
+            @RequestParam("per_page", required = false) pageSize: Int?,
+            @RequestParam("startTime", required = false) startTime: String?,
+            @RequestParam("endTime", required = false) endTime: String?
+    ) = obdDataService.getLogoutData(deviceCode, pageNum, pageSize, startTime, endTime)
+
+    @GetMapping("/obdInfo/")
+    fun getObdInfo(
+            @RequestParam("deviceCode") deviceCode: String,
+            @RequestParam("page", required = false) pageNum: Int?,
+            @RequestParam("per_page", required = false) pageSize: Int?
+    ) = obdDataService.getObdInfo(deviceCode, pageNum, pageSize)
+
+    @GetMapping("/dataStream/{deviceCode}")
+    fun getDataStream(
+            @PathVariable("deviceCode") deviceCode: String,
+            @RequestParam("page", required = false) pageNum: Int?,
+            @RequestParam("per_page", required = false) pageSize: Int?,
+            @RequestParam("startTime", required = false) startTime: String?,
+            @RequestParam("endTime", required = false) endTime: String?
+    ) = obdDataService.getDataStream(deviceCode, pageNum, pageSize, startTime, endTime)
+
+    @GetMapping("/dataStream/count")
+    fun getDataStreamCount(
+            @RequestParam("deviceCode") deviceCode: String = "",
+            @RequestParam("startTime", required = false) startTime: String?,
+            @RequestParam("endTime", required = false) endTime: String?
+    ) = obdDataService.getDataStreamCount(deviceCode, startTime, endTime)
+
+    @GetMapping("/coordinate/{deviceCode}")
+    fun getCoordinate(
+            @PathVariable("deviceCode") deviceCode: String
+    ) = obdDataService.getCoordinate(deviceCode)
+
+    @GetMapping("/coordinate/track")
+    fun getTrack(
+            @RequestParam("deviceCode") deviceCode: String,
+            @RequestParam("startTime") startTime: String,
+            @RequestParam("endTime") endTime: String
+    ) = obdDataService.getTrack(deviceCode, startTime, endTime)
+
+    @GetMapping("/coordinate/latest")
+    fun getCoordinate(
+            @RequestParam("page", required = false) pageNum: Int?,
+            @RequestParam("per_page", required = false) pageSize: Int?
+    ) = obdDataService.getLatestCoordinate(pageNum, pageSize)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdThresholdController.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdThresholdController.kt
new file mode 100644
index 0000000..7788d06
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdThresholdController.kt
@@ -0,0 +1,32 @@
+package com.flightfeather.uav.lightshare.web
+
+import com.flightfeather.uav.lightshare.bean.ThresholdValueVo
+import com.flightfeather.uav.lightshare.service.ObdThresholdValueService
+import org.springframework.web.bind.annotation.*
+
+/**
+ * @author riku
+ * Date: 2019/9/5
+ */
+@RestController
+@RequestMapping("uav/threshold")
+class ObdThresholdController(val obdThresholdValueService: ObdThresholdValueService) {
+
+    @GetMapping("/{vinCode}")
+    fun getDataByVinCode(
+            @PathVariable("vinCode") vinCode: String
+    ) = obdThresholdValueService.getDataByVinCode(vinCode)
+
+    @PostMapping("/update")
+    fun update(
+            @RequestParam("userId") userId: String,
+            @RequestBody thresholdValueVo: ThresholdValueVo
+    ) = obdThresholdValueService.update(userId, thresholdValueVo)
+
+    @PutMapping("/save")
+    fun save(
+            @RequestParam("userId") userId: String,
+            @RequestBody thresholdValueVo: ThresholdValueVo
+    ) = obdThresholdValueService.save(userId, thresholdValueVo)
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdUserController.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdUserController.kt
new file mode 100644
index 0000000..1fa99ae
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/web/ObdUserController.kt
@@ -0,0 +1,22 @@
+package com.flightfeather.uav.lightshare.web
+
+import com.flightfeather.uav.lightshare.service.ObdUserService
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.PathVariable
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+/**
+ * @author riku
+ * Date: 2019/9/6
+ */
+@RestController
+@RequestMapping("uav/user")
+class ObdUserController(val obdUserService: ObdUserService) {
+
+    @GetMapping("/info/{userId}")
+    fun getUserInfo(
+            @PathVariable("userId") userId: String
+    ) = obdUserService.getUserInfo(userId)
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/web/VehicleInfoController.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/web/VehicleInfoController.kt
new file mode 100644
index 0000000..e743d5e
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/web/VehicleInfoController.kt
@@ -0,0 +1,22 @@
+package com.flightfeather.uav.lightshare.web
+
+import com.flightfeather.uav.lightshare.service.VehicleService
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RequestParam
+import org.springframework.web.bind.annotation.RestController
+
+/**
+ * @author riku
+ * Date: 2019/10/25
+ */
+@RestController
+@RequestMapping("uav/vehicle")
+class VehicleInfoController(val vehicleService: VehicleService) {
+
+    @GetMapping("/info")
+    fun getVehicleInfo(
+            @RequestParam("page", required = false) pageNum: Int?,
+            @RequestParam("per_page", required = false) pageSize: Int?
+    ) = vehicleService.getVehicleInfo(pageNum, pageSize)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/CarLoginRepository.kt b/src/main/kotlin/com/flightfeather/uav/repository/CarLoginRepository.kt
new file mode 100644
index 0000000..fef16d8
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/CarLoginRepository.kt
@@ -0,0 +1,21 @@
+package com.flightfeather.uav.repository
+
+import com.flightfeather.uav.lightshare.bean.CarLoginVo
+import com.flightfeather.uav.socket.bean.ObdPackageData
+
+/**
+ * @author riku
+ * Date: 2019/9/17
+ */
+interface CarLoginRepository {
+
+    /**
+     * 淇濆瓨杞﹁締鐧诲叆淇℃伅
+     */
+    fun saveCarLogin(packageData: ObdPackageData): Boolean
+
+    /**
+     * 鏍规嵁缁堢璁惧鐮佽幏鍙栫櫥褰曟暟鎹�
+     */
+    fun getLoginData(deviceCode: String, pageNum: Int?, pageSize: Int?, startTime: String?, endTime: String?): List<CarLoginVo>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/CarLogoutRepository.kt b/src/main/kotlin/com/flightfeather/uav/repository/CarLogoutRepository.kt
new file mode 100644
index 0000000..5304c2b
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/CarLogoutRepository.kt
@@ -0,0 +1,21 @@
+package com.flightfeather.uav.repository
+
+import com.flightfeather.uav.lightshare.bean.CarLogoutVo
+import com.flightfeather.uav.socket.bean.ObdPackageData
+
+/**
+ * @author riku
+ * Date: 2019/9/17
+ */
+interface CarLogoutRepository {
+
+    /**
+     * 淇濆瓨 杞﹁締鐧诲嚭鍏ヤ俊鎭�
+     */
+    fun saveCarLogout(packageData: ObdPackageData): Boolean
+
+    /**
+     * 鏍规嵁缁堢璁惧鐮佽幏鍙栫櫥鍑烘暟鎹�
+     */
+    fun getLogoutData(deviceCode: String, pageNum: Int?, pageSize: Int?, startTime: String?, endTime: String?): List<CarLogoutVo>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/DataStreamRepository.kt b/src/main/kotlin/com/flightfeather/uav/repository/DataStreamRepository.kt
new file mode 100644
index 0000000..ad1f279
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/DataStreamRepository.kt
@@ -0,0 +1,32 @@
+package com.flightfeather.uav.repository
+
+import com.flightfeather.uav.domain.entity.DataStream
+import com.flightfeather.uav.lightshare.bean.DataStreamVo
+import com.flightfeather.uav.socket.bean.ObdPackageData
+
+/**
+ * @author riku
+ * Date: 2019/9/17
+ */
+interface DataStreamRepository {
+
+    /**
+     * 淇濆瓨 瀹炴椂淇℃伅鎴栬ˉ浼犱俊鎭� 涓殑 鏁版嵁娴佷俊鎭� 鍜� 琛ュ厖鏁版嵁娴�
+     */
+    fun saveDataStream(packageData: ObdPackageData): Boolean
+
+    /**
+     * 鏍规嵁缁堢璁惧鐮佽幏鍙栨暟鎹祦鏁版嵁
+     */
+    fun getDataStream(deviceCode: String, pageNum: Int?, pageSize: Int?, startTime: String?, endTime: String?): List<DataStreamVo>
+
+    /**
+     * 鏍规嵁缁堢璁惧鐮佽幏鍙栨暟鎹祦鏁版嵁璁℃暟
+     */
+    fun getDataStreamCount(deviceCode: String, startTime: String?, endTime: String?): Int
+
+    /**
+     * 鑾峰彇涓�杈嗚溅鏈�鏂扮殑涓�鏉$姸鎬佷俊鎭�
+     */
+    fun getLatestDataStream(deviceCode: String): DataStream?
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/ObdAlarmRepository.kt b/src/main/kotlin/com/flightfeather/uav/repository/ObdAlarmRepository.kt
new file mode 100644
index 0000000..0dff00d
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/ObdAlarmRepository.kt
@@ -0,0 +1,22 @@
+package com.flightfeather.uav.repository
+
+import com.flightfeather.uav.lightshare.bean.AlarmDataVo
+
+/**
+ * obd璀︽姤鐩稿叧鏁版嵁搴撴搷浣滄帴鍙�
+ * @author riku
+ * Date: 2019/9/5
+ */
+interface ObdAlarmRepository {
+
+    /**
+     * 瀛樺偍璀︽姤鏁版嵁
+     */
+    fun saveObdAlarm(alarmDataVo: AlarmDataVo): Boolean
+
+    /**
+     * 閫氳繃姹借溅vin鐮佽幏鍙栬鎶ユ暟鎹�
+     */
+    fun getAlarmByVinCode(vinCode: String, pageNum: Int?, pageSize: Int?): MutableList<AlarmDataVo>
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/ObdDataRepository.kt b/src/main/kotlin/com/flightfeather/uav/repository/ObdDataRepository.kt
new file mode 100644
index 0000000..8b6fb27
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/ObdDataRepository.kt
@@ -0,0 +1,25 @@
+package com.flightfeather.uav.repository
+
+import com.flightfeather.uav.lightshare.bean.ObdDataVo
+import com.flightfeather.uav.socket.bean.ObdPackageData
+
+/**
+ * obd鏁版嵁鐩稿叧鏁版嵁搴撴搷浣滄帴鍙�
+ * @author riku
+ * Date: 2019/8/27
+ */
+interface ObdDataRepository {
+
+    /**
+     * 瀛樺偍obd鏁版嵁
+     */
+    fun saveObdData(data: ObdDataVo): Boolean
+
+    /**
+     * 閫氳繃姹借溅vin鐮佽幏鍙栨渶鏂版暟鎹�
+     */
+    fun getDataByVinCode(vinCode: String?, pageNum: Int?, pageSize: Int?): MutableList<ObdDataVo>
+
+    fun saveObdData(packageData: ObdPackageData):Boolean
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/ObdInfoRepository.kt b/src/main/kotlin/com/flightfeather/uav/repository/ObdInfoRepository.kt
new file mode 100644
index 0000000..5a71b2a
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/ObdInfoRepository.kt
@@ -0,0 +1,25 @@
+package com.flightfeather.uav.repository
+
+import com.flightfeather.uav.socket.bean.ObdInfo
+import com.flightfeather.uav.socket.bean.ObdPackageData
+import com.flightfeather.uav.socket.bean.RealTimeData
+import com.flightfeather.uav.socket.bean.ReplacementData
+
+/**
+ * @author riku
+ * Date: 2019/9/17
+ */
+interface ObdInfoRepository {
+
+    /**
+     * 淇濆瓨 瀹炴椂淇℃伅 @see [RealTimeData] 鎴栬ˉ浼犱俊鎭� @see [ReplacementData]  涓殑 uav 鏁版嵁 @see [ObdInfo]
+     */
+    fun saveObdInfo(packageData: ObdPackageData): Boolean
+
+    /**
+     * 鏍规嵁缁堢璁惧鐮佽幏鍙杘bd鏁版嵁
+     */
+    fun getObdInfo(deviceCode: String, pageNum: Int?, pageSize: Int?): List<com.flightfeather.uav.domain.entity.ObdInfo>
+
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/ObdThresholdValueRepository.kt b/src/main/kotlin/com/flightfeather/uav/repository/ObdThresholdValueRepository.kt
new file mode 100644
index 0000000..11e1cd5
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/ObdThresholdValueRepository.kt
@@ -0,0 +1,27 @@
+package com.flightfeather.uav.repository
+
+import com.flightfeather.uav.lightshare.bean.ThresholdValueVo
+
+/**
+ * obd璀︽姤闃堝�肩浉鍏虫暟鎹簱鎿嶄綔鎺ュ彛
+ * @author riku
+ * Date: 2019/9/5
+ */
+interface ObdThresholdValueRepository {
+
+    /**
+     * 瀛樺偍闃堝��
+     */
+    fun save(userId: String, thresholdValueVo: ThresholdValueVo): Boolean
+
+    /**
+     * 鏇存柊闃堝��
+     */
+    fun update(userId: String, thresholdValueVo: ThresholdValueVo): Boolean
+
+    /**
+     * 閫氳繃姹借溅vin鐮佽幏鍙栭槇鍊兼暟鎹�
+     */
+    fun getByVinCode(vinCode: String): ThresholdValueVo?
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/ObdUserRepository.kt b/src/main/kotlin/com/flightfeather/uav/repository/ObdUserRepository.kt
new file mode 100644
index 0000000..a6a3376
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/ObdUserRepository.kt
@@ -0,0 +1,13 @@
+package com.flightfeather.uav.repository
+
+import com.flightfeather.uav.lightshare.bean.ObdUserVo
+
+/**
+ * @author riku
+ * Date: 2019/9/6
+ */
+interface ObdUserRepository {
+
+    fun getUserInfo(userId: String): ObdUserVo?
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/OriginDataRepository.kt b/src/main/kotlin/com/flightfeather/uav/repository/OriginDataRepository.kt
new file mode 100644
index 0000000..6a5b69a
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/OriginDataRepository.kt
@@ -0,0 +1,16 @@
+package com.flightfeather.uav.repository
+
+import com.flightfeather.uav.socket.bean.ObdPackageData
+
+/**
+ * @author riku
+ * Date: 2019/9/17
+ */
+interface OriginDataRepository {
+
+    /**
+     * 淇濆瓨鍓嶇浼犺緭鐨勫師濮嬫暟鎹� @see [ObdPackageData]
+     */
+    fun saveOriginData(packageData: ObdPackageData, msg: String): Boolean
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/VehicleRepository.kt b/src/main/kotlin/com/flightfeather/uav/repository/VehicleRepository.kt
new file mode 100644
index 0000000..eed3531
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/VehicleRepository.kt
@@ -0,0 +1,15 @@
+package com.flightfeather.uav.repository
+
+import com.flightfeather.uav.domain.entity.VehicleInfo
+
+/**
+ * @author riku
+ * Date: 2019/10/25
+ */
+interface VehicleRepository {
+
+    /**
+     * 鑾峰彇杞﹁締淇℃伅
+     */
+    fun getVehicleInfo(pageNum: Int?, pageSize: Int?): List<VehicleInfo>
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/impl/CarLoginDaoImpl.kt b/src/main/kotlin/com/flightfeather/uav/repository/impl/CarLoginDaoImpl.kt
new file mode 100644
index 0000000..179e19c
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/impl/CarLoginDaoImpl.kt
@@ -0,0 +1,68 @@
+package com.flightfeather.uav.repository.impl
+
+import com.flightfeather.uav.domain.entity.CarLogin
+import com.flightfeather.uav.domain.mapper.CarLoginMapper
+import com.flightfeather.uav.lightshare.bean.CarLoginVo
+import com.flightfeather.uav.repository.CarLoginRepository
+import com.flightfeather.uav.socket.bean.CarRegisterData
+import com.flightfeather.uav.socket.bean.ObdPackageData
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+import com.github.pagehelper.PageHelper
+import org.springframework.beans.BeanUtils
+import org.springframework.stereotype.Repository
+import tk.mybatis.mapper.entity.Example
+
+/**
+ * @author riku
+ * Date: 2019/9/17
+ */
+@Repository
+class CarLoginDaoImpl(val carLoginMapper: CarLoginMapper) : CarLoginRepository {
+
+    override fun saveCarLogin(packageData: ObdPackageData): Boolean {
+
+        return if (packageData.commandUnit == ObdCommandUnit.CarRegister.value) {
+            val carLogin = CarLogin().apply {
+                obdDeviceCode = packageData.deviceCode
+            }
+
+            packageData.dataUnit.forEach {
+                when (it) {
+                    is CarRegisterData -> carLogin.apply {
+                        loginDataTime = it.time
+                        loginSerialNum = it.serialNum
+                        loginSimCode = it.SIMCode
+                    }
+                }
+            }
+
+            carLoginMapper.insert(carLogin) == 1
+        } else {
+            false
+        }
+    }
+
+    override fun getLoginData(deviceCode: String, pageNum: Int?, pageSize: Int?, startTime: String?, endTime: String?): List<CarLoginVo> {
+        val example = Example(CarLogin::class.java).apply {
+            createCriteria().andEqualTo("obdDeviceCode", deviceCode).run {
+                startTime?.let { andGreaterThanOrEqualTo("loginDataTime", it) }
+                endTime?.let { andLessThanOrEqualTo("loginDataTime", it) }
+                orderBy("loginDataTime").desc()
+            }
+        }
+
+        //鍒嗛〉
+        val offset = (pageSize?.times(pageNum?.minus(1) ?: 0)) ?: 0
+        PageHelper.offsetPage<CarLogin>(offset, pageSize ?: 10)
+        val result = carLoginMapper.selectByExample(example)
+
+        val resultList = mutableListOf<CarLoginVo>()
+        result.forEach {
+            val vo = CarLoginVo()
+            BeanUtils.copyProperties(it, vo)
+            resultList.add(vo)
+        }
+
+        return resultList
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/impl/CarLogoutDaoImpl.kt b/src/main/kotlin/com/flightfeather/uav/repository/impl/CarLogoutDaoImpl.kt
new file mode 100644
index 0000000..8025dd7
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/impl/CarLogoutDaoImpl.kt
@@ -0,0 +1,65 @@
+package com.flightfeather.uav.repository.impl
+
+import com.flightfeather.uav.domain.entity.CarLogout
+import com.flightfeather.uav.domain.mapper.CarLogoutMapper
+import com.flightfeather.uav.lightshare.bean.CarLogoutVo
+import com.flightfeather.uav.repository.CarLogoutRepository
+import com.flightfeather.uav.socket.bean.CarLogOutData
+import com.flightfeather.uav.socket.bean.ObdPackageData
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+import com.github.pagehelper.PageHelper
+import org.springframework.beans.BeanUtils
+import org.springframework.stereotype.Repository
+import tk.mybatis.mapper.entity.Example
+
+/**
+ * @author riku
+ * Date: 2019/9/17
+ */
+@Repository
+class CarLogoutDaoImpl(val carLogoutMapper: CarLogoutMapper): CarLogoutRepository {
+    override fun saveCarLogout(packageData: ObdPackageData): Boolean {
+        return if (packageData.commandUnit == ObdCommandUnit.CarLogOut.value) {
+            val carLogout = CarLogout().apply {
+                obdDeviceCode = packageData.deviceCode
+            }
+
+            packageData.dataUnit.forEach {
+                when (it) {
+                    is CarLogOutData -> carLogout.apply {
+                        logoutDataTime = it.time
+                        logoutSerialNum = it.serialNum
+                    }
+                }
+            }
+
+            carLogoutMapper.insert(carLogout) == 1
+        } else {
+            false
+        }
+    }
+
+    override fun getLogoutData(deviceCode: String, pageNum: Int?, pageSize: Int?, startTime: String?, endTime: String?): List<CarLogoutVo> {
+        val example = Example(CarLogout::class.java).apply {
+            createCriteria().andEqualTo("obdDeviceCode", deviceCode).run {
+                startTime?.let { andGreaterThanOrEqualTo("loginDataTime", it) }
+                endTime?.let { andLessThanOrEqualTo("loginDataTime", it) }
+                orderBy("loginDataTime").desc()
+            }
+        }
+
+        //鍒嗛〉
+        val offset = (pageSize?.times(pageNum?.minus(1) ?: 0)) ?: 0
+        PageHelper.offsetPage<CarLogout>(offset, pageSize ?: 10)
+        val result = carLogoutMapper.selectByExample(example)
+
+        val resultList = mutableListOf<CarLogoutVo>()
+        result.forEach {
+            val vo = CarLogoutVo()
+            BeanUtils.copyProperties(it, vo)
+            resultList.add(vo)
+        }
+
+        return resultList
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/impl/DataStreamDaoImpl.kt b/src/main/kotlin/com/flightfeather/uav/repository/impl/DataStreamDaoImpl.kt
new file mode 100644
index 0000000..510c97b
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/impl/DataStreamDaoImpl.kt
@@ -0,0 +1,157 @@
+package com.flightfeather.uav.repository.impl
+
+import com.flightfeather.uav.domain.entity.DataStream
+import com.flightfeather.uav.domain.mapper.DataStreamMapper
+import com.flightfeather.uav.domain.mapper.VehicleInfoMapper
+import com.flightfeather.uav.lightshare.bean.DataStreamVo
+import com.flightfeather.uav.repository.DataStreamRepository
+import com.flightfeather.uav.socket.bean.EngineDataStream
+import com.flightfeather.uav.socket.bean.ObdPackageData
+import com.flightfeather.uav.socket.bean.SupplementDataStream
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+import com.github.pagehelper.PageHelper
+import org.springframework.beans.BeanUtils
+import org.springframework.stereotype.Repository
+import tk.mybatis.mapper.entity.Example
+import java.text.SimpleDateFormat
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/17
+ */
+@Repository
+class DataStreamDaoImpl(val dataStreamMapper: DataStreamMapper, val vehicleInfoMapper: VehicleInfoMapper): DataStreamRepository {
+
+    override fun saveDataStream(packageData: ObdPackageData): Boolean {
+
+        return if (packageData.commandUnit == ObdCommandUnit.RealTimeData.value
+                || packageData.commandUnit == ObdCommandUnit.ReplacementData.value) {
+
+            val dataStream = DataStream().apply {
+                obdDeviceCode = packageData.deviceCode
+                obdStatus = packageData.commandUnit == ObdCommandUnit.ReplacementData.value
+            }
+
+            packageData.dataUnit.forEach {
+                dataStream.apply {
+                    obdDataTime = it.time
+                    obdSerialNum = it.serialNum
+                }
+                when (it) {
+                    is EngineDataStream -> dataStream.apply {
+                        //fixme 姝ゅ鐩稿悓灞炴�у彲鐢� [BeanUtil] 宸ュ叿鏉ュ揩閫熻祴鍊硷紝浣嗗洜涓哄苟涓嶆槸鍏ㄩ儴灞炴�ч兘鐩稿悓锛屽彲鑳藉鏄撲骇鐢熻瑙�
+                        obdSpeed = it.obdSpeed
+                        obdAirPressure = it.obdAirPressure
+                        obdEngineTorque = it.obdEngineTorque
+                        obdFrictionTorque = it.obdFrictionTorque
+                        obdEngineRpm = it.obdEngineRpm
+                        obdEngineFuelFlow = it.obdEngineFuelFlow
+                        obdScrUpstreamNox = it.obdScrUpstreamNox
+                        obdScrDownstreamNox = it.obdScrDownstreamNox
+                        obdRemainReactant = it.obdRemainReactant
+                        obdAirInput = it.obdAirInput
+                        obdScrInputTemp = it.obdScrInputTemp
+                        obdScrOutputTemp = it.obdScrOutputTemp
+                        obdDpf = it.obdDpf
+                        obdEngineCoolantTemp = it.obdEngineCoolantTemp
+                        obdFuelLevel = it.obdFuelLevel
+                        obdLocationStatus = it.obdLocationStatus?.toString(2)
+                        obdLong = it.obdLong
+                        obdLat = it.obdLat
+                        obdTotalMileage = it.obdTotalMileage
+                    }
+                    is SupplementDataStream -> dataStream.apply {
+                        obdEngineTorqueMode = it.obdEngineTorqueMode
+                        obdAcceleratorPedal = it.obdAcceleratorPedal
+                        obdTotalOilConsumption = it.obdTotalOilConsumption
+                        obdUreaBoxTemp = it.obdUreaBoxTemp
+                        obdUreaVolume = it.obdUreaVolume
+                        obdTotalUreaConsume = it.obdTotalUreaConsume
+                        obdDpfTemp = it.obdDpfTemp
+                    }
+                }
+            }
+
+            dataStreamMapper.insert(dataStream) == 1
+        } else {
+            false
+        }
+    }
+
+    override fun getDataStream(deviceCode: String, pageNum: Int?, pageSize: Int?, startTime: String?, endTime: String?): List<DataStreamVo> {
+        val sf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
+        val example = Example(DataStream::class.java).apply {
+            createCriteria().andEqualTo("obdDeviceCode", deviceCode).run {
+                startTime?.let {
+                    try {
+                        val st = sf.parse(startTime)
+                        andGreaterThanOrEqualTo("obdDataTime", st)
+                    } catch (e: Throwable) {
+                        e.printStackTrace()
+                    }
+                }
+                endTime?.let {
+                    try {
+                        val et = sf.parse(endTime)
+                        andLessThanOrEqualTo("obdDataTime", et)
+                    } catch (e: Throwable) {
+                        e.printStackTrace()
+                    }
+                }
+                orderBy("obdDataTime").desc()
+            }
+        }
+
+        //鍒嗛〉
+        val offset = (pageSize?.times(pageNum?.minus(1) ?: 0)) ?: 0
+        PageHelper.offsetPage<DataStream>(offset, pageSize ?: 10)
+        val result = dataStreamMapper.selectByExample(example)
+
+        val resultList = mutableListOf<DataStreamVo>()
+        result.forEach {
+            val vo = DataStreamVo()
+            BeanUtils.copyProperties(it, vo)
+            resultList.add(vo)
+        }
+
+        return resultList
+    }
+
+    override fun getDataStreamCount(deviceCode: String, startTime: String?, endTime: String?): Int {
+        val sf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA)
+        val example = Example(DataStream::class.java).apply {
+            createCriteria().andEqualTo("obdDeviceCode", deviceCode).run {
+                startTime?.let {
+                    try {
+                        val st = sf.parse(startTime)
+                        andGreaterThanOrEqualTo("obdDataTime", st)
+                    } catch (e: Throwable) {
+                        e.printStackTrace()
+                    }
+                }
+                endTime?.let {
+                    try {
+                        val et = sf.parse(endTime)
+                        andLessThanOrEqualTo("obdDataTime", et)
+                    } catch (e: Throwable) {
+                        e.printStackTrace()
+                    }
+                }
+                orderBy("obdDataTime").desc()
+            }
+        }
+
+        return dataStreamMapper.selectCountByExample(example)
+    }
+
+    override fun getLatestDataStream(deviceCode: String): DataStream? {
+        val example = Example(DataStream::class.java).apply {
+            createCriteria().andEqualTo("obdDeviceCode", deviceCode)
+            orderBy("obdDataTime").desc()
+        }
+        //鑾峰彇鏈�鏂扮殑涓�涓�
+        PageHelper.offsetPage<DataStream>(0, 1)
+        return dataStreamMapper.selectByExample(example).takeIf { it.isNotEmpty() }?.get(0)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/impl/ObdAlarmDaoImpl.kt b/src/main/kotlin/com/flightfeather/uav/repository/impl/ObdAlarmDaoImpl.kt
new file mode 100644
index 0000000..6d301f0
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/impl/ObdAlarmDaoImpl.kt
@@ -0,0 +1,46 @@
+package com.flightfeather.uav.repository.impl
+
+import com.flightfeather.uav.domain.entity.AlarmData
+import com.flightfeather.uav.domain.mapper.AlarmDataMapper
+import com.flightfeather.uav.lightshare.bean.AlarmDataVo
+import com.flightfeather.uav.repository.ObdAlarmRepository
+import com.github.pagehelper.PageHelper
+import org.springframework.beans.BeanUtils
+import org.springframework.stereotype.Repository
+import tk.mybatis.mapper.entity.Example
+
+/**
+ * @author riku
+ * Date: 2019/9/5
+ */
+@Repository
+class ObdAlarmDaoImpl(val alarmDataMapper: AlarmDataMapper) : ObdAlarmRepository {
+
+    override fun saveObdAlarm(alarmDataVo: AlarmDataVo): Boolean {
+        val alarmData = AlarmData()
+        BeanUtils.copyProperties(alarmDataVo, alarmData)
+        return alarmDataMapper.insert(alarmData) == 1
+    }
+
+    override fun getAlarmByVinCode(vinCode: String, pageNum: Int?, pageSize: Int?): MutableList<AlarmDataVo> {
+        val example = Example(AlarmData::class.java).apply {
+            createCriteria().andEqualTo("obdVin", vinCode)
+            orderBy("alarmTime").desc()
+        }
+
+        //鍒嗛〉
+        val offset = (pageSize?.times(pageNum?.minus(1) ?: 0)) ?: 0
+        PageHelper.offsetPage<AlarmData>(offset, pageSize ?: 10)
+        val result = alarmDataMapper.selectByExample(example)
+
+        val resultList = mutableListOf<AlarmDataVo>()
+        result.forEach {
+            val vo = AlarmDataVo()
+            BeanUtils.copyProperties(it, vo)
+            resultList.add(vo)
+        }
+        
+        return resultList
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/impl/ObdDataDaoImpl.kt b/src/main/kotlin/com/flightfeather/uav/repository/impl/ObdDataDaoImpl.kt
new file mode 100644
index 0000000..c2a84c5
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/impl/ObdDataDaoImpl.kt
@@ -0,0 +1,147 @@
+package com.flightfeather.uav.repository.impl
+
+import com.flightfeather.uav.domain.entity.ObdData
+import com.flightfeather.uav.domain.mapper.ObdDataMapper
+import com.flightfeather.uav.lightshare.bean.ObdDataVo
+import com.flightfeather.uav.repository.ObdDataRepository
+import com.flightfeather.uav.socket.bean.*
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+import com.github.pagehelper.PageHelper
+import org.springframework.beans.BeanUtils
+import org.springframework.stereotype.Repository
+import tk.mybatis.mapper.entity.Example
+
+/**
+ * obd鏁版嵁鐩稿叧鏁版嵁搴撴搷浣滃疄鐜�
+ * @author riku
+ * Date: 2019/8/27
+ */
+@Repository
+class ObdDataDaoImpl(val obdDataMapper: ObdDataMapper) : ObdDataRepository {
+
+    override fun saveObdData(data: ObdDataVo): Boolean {
+        val obdData = ObdData()
+        BeanUtils.copyProperties(data, obdData)
+        return obdDataMapper.insert(obdData) == 1
+    }
+
+    override fun getDataByVinCode(vinCode: String?, pageNum: Int?, pageSize: Int?): MutableList<ObdDataVo> {
+        val example = Example(ObdData::class.java).apply {
+            createCriteria().andEqualTo("obdVin", vinCode)
+            orderBy("obdTime").desc()
+        }
+
+        //鍒嗛〉
+        val offset = (pageSize?.times(pageNum?.minus(1) ?: 0)) ?: 0
+        PageHelper.offsetPage<ObdData>(offset, pageSize ?: 10)
+        val result = obdDataMapper.selectByExample(example)
+
+        val resultList = mutableListOf<ObdDataVo>()
+        result.forEach {
+            val vo = ObdDataVo()
+            BeanUtils.copyProperties(it, vo)
+            resultList.add(vo)
+        }
+
+        return resultList
+    }
+
+    override fun saveObdData(packageData: ObdPackageData): Boolean {
+        val obdData = ObdData().apply {
+            obdVin = packageData.deviceCode
+        }
+        when (packageData.commandUnit) {
+            ObdCommandUnit.CarRegister.value -> {
+                packageData.dataUnit.forEach {
+                    when (it) {
+                        is CarRegisterData -> {
+                            obdData.apply {
+                                obdTime = it.time
+                            }
+                        }
+                    }
+                }
+            }
+            ObdCommandUnit.RealTimeData.value,
+            ObdCommandUnit.ReplacementData.value -> {
+                packageData.dataUnit.forEach {
+                    when (it) {
+                        is com.flightfeather.uav.socket.bean.ObdInfo -> {
+                            obdData.apply {
+                                obdTime = it.time
+                                obdProtocol = it.obdProtocol
+                                obdMil = it.obdMil
+                                obdIdCode = it.obdCrn
+                                obdVerificationCode = it.obdCvn
+                                obdFaultCodeNum = it.obdFaultCodeNum
+                                obdFaultCode = it.obdFaultCode
+                            }
+                        }
+                        is EngineDataStream -> {
+                            obdData.apply {
+                                obdTime = it.time
+                                obdLng = it.obdLong
+                                obdLat = it.obdLat
+                                obdSpeed = it.obdSpeed?.toInt()
+                                obdAirPressure = it.obdAirPressure
+                                obdEngineTorque = it.obdEngineTorque
+                                obdFrictionTorque = it.obdFrictionTorque
+                                obdEngineRpm = it.obdEngineRpm?.toInt()
+                                obdStartFuelFlow = it.obdEngineFuelFlow
+                                obdScrUpstreamNo = it.obdScrUpstreamNox
+                                obdScrDownstreamNo = it.obdScrDownstreamNox
+                                obdRemainReactant = it.obdRemainReactant
+                                obdAirInput = it.obdAirInput
+                                obdScrInputTemp = it.obdScrInputTemp
+                                obdScrOutputTemp = it.obdScrOutputTemp
+                                obdDpf = it.obdDpf
+                                obdEngineCoolantTemp = it.obdEngineCoolantTemp
+                                obdFuelLevel = it.obdFuelLevel
+                                obdLocationStatus = it.obdLocationStatus
+                                obdTotalMileage = it.obdTotalMileage
+                            }
+                        }
+                        is SupplementDataStream -> {
+                            obdData.apply {
+                                obdTime = it.time
+                                obdEngineTorqueMode = it.obdEngineTorqueMode?.toString()
+                                obdAcceleratorPedal = it.obdAcceleratorPedal
+                                obdTotalOilConsumption = it.obdTotalOilConsumption
+                                obdUreaBoxTemp = it.obdUreaBoxTemp
+                                obdUreaVolume = it.obdUreaVolume?.toInt()
+                                obdTotalUreaConsume = it.obdTotalUreaConsume
+                                obdDpfTemp = it.obdDpfTemp
+//                                obdFirmwareVersion =
+                            }
+                        }
+                    }
+                }
+
+            }
+            ObdCommandUnit.CarLogOut.value -> {
+                packageData.dataUnit.forEach {
+                    when (it) {
+                        is CarLogOutData -> {
+                            obdData.apply {
+                                obdTime = it.time
+                            }
+                        }
+                    }
+                }
+            }
+            ObdCommandUnit.TimeCalibration.value -> {
+                packageData.dataUnit.forEach {
+                    when (it) {
+                        is TimeCalibrationData -> {
+                            obdData.apply {
+                                obdTime = it.time
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return obdDataMapper.insert(obdData) == 1
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/impl/ObdInfoDaoImpl.kt b/src/main/kotlin/com/flightfeather/uav/repository/impl/ObdInfoDaoImpl.kt
new file mode 100644
index 0000000..967a02a
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/impl/ObdInfoDaoImpl.kt
@@ -0,0 +1,68 @@
+package com.flightfeather.uav.repository.impl
+
+import com.flightfeather.uav.domain.entity.ObdInfo
+import com.flightfeather.uav.domain.mapper.ObdInfoMapper
+import com.flightfeather.uav.repository.ObdInfoRepository
+import com.flightfeather.uav.socket.bean.ObdPackageData
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+import com.github.pagehelper.PageHelper
+import org.springframework.stereotype.Repository
+import tk.mybatis.mapper.entity.Example
+
+/**
+ * @author riku
+ * Date: 2019/9/17
+ */
+@Repository
+class ObdInfoDaoImpl(val obdInfoMapper: ObdInfoMapper) : ObdInfoRepository {
+
+    override fun saveObdInfo(packageData: ObdPackageData): Boolean {
+
+        return if (packageData.commandUnit == ObdCommandUnit.RealTimeData.value
+                || packageData.commandUnit == ObdCommandUnit.ReplacementData.value) {
+
+            val obdInfo = ObdInfo().apply {
+                obdDeviceCode = packageData.deviceCode
+                obdStatus = packageData.commandUnit == ObdCommandUnit.ReplacementData.value
+            }
+
+            packageData.dataUnit.forEach {
+                when (it) {
+                    is com.flightfeather.uav.socket.bean.ObdInfo -> {
+                        obdInfo.apply {
+                            obdDataTime = it.time
+                            obdSerialNum = it.serialNum
+                            obdProtocol = it.obdProtocol
+                            obdMil = it.obdMil
+                            obdDiagnosisSupportStatus = it.diagnosisSupportStatus
+                            obdDiagnosisReadyStatus = it.diagnosisReadyStatus
+                            obdVin = it.obdVin
+                            obdCrn = it.obdCrn
+                            obdCvn = it.obdCvn
+                            obdIupr = it.iupr
+                            obdFaultCodeNum = it.obdFaultCodeNum
+                            obdFaultCode = it.obdFaultCode
+                        }
+                    }
+                }
+            }
+
+            obdInfoMapper.insert(obdInfo) == 1
+        } else {
+            false
+        }
+    }
+
+    override fun getObdInfo(deviceCode: String, pageNum: Int?, pageSize: Int?): List<ObdInfo> {
+        val example = Example(ObdInfo::class.java).apply {
+            createCriteria().andEqualTo("obdDeviceCode", deviceCode).run {
+                orderBy("obdDataTime").desc()
+            }
+        }
+
+        //鍒嗛〉
+        val offset = (pageSize?.times(pageNum?.minus(1) ?: 0)) ?: 0
+        PageHelper.offsetPage<ObdInfo>(offset, pageSize ?: 10)
+        return obdInfoMapper.selectByExample(example)
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/impl/ObdThresholdValueDaoImpl.kt b/src/main/kotlin/com/flightfeather/uav/repository/impl/ObdThresholdValueDaoImpl.kt
new file mode 100644
index 0000000..6461bed
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/impl/ObdThresholdValueDaoImpl.kt
@@ -0,0 +1,56 @@
+package com.flightfeather.uav.repository.impl
+
+import com.flightfeather.uav.domain.entity.ThresholdValue
+import com.flightfeather.uav.domain.mapper.ThresholdValueMapper
+import com.flightfeather.uav.lightshare.bean.ThresholdValueVo
+import com.flightfeather.uav.repository.ObdThresholdValueRepository
+import org.springframework.beans.BeanUtils
+import org.springframework.stereotype.Repository
+import tk.mybatis.mapper.entity.Example
+
+/**
+ * @author riku
+ * Date: 2019/9/5
+ */
+@Repository
+class ObdThresholdValueDaoImpl(val obdThresholdValueMapper: ThresholdValueMapper) : ObdThresholdValueRepository {
+
+    override fun save(userId: String, thresholdValueVo: ThresholdValueVo): Boolean {
+        val thresholdValue = ThresholdValue()
+        BeanUtils.copyProperties(thresholdValueVo, thresholdValue)
+        val example = Example(ThresholdValue::class.java).apply {
+            createCriteria().andEqualTo("obdVin", thresholdValueVo.obdVin)
+        }
+        val tempResult = obdThresholdValueMapper.selectByExample(example)
+        return if (tempResult.isNotEmpty())
+            false
+        else
+            obdThresholdValueMapper.insert(thresholdValue) == 1
+    }
+
+    override fun update(userId: String, thresholdValueVo: ThresholdValueVo): Boolean {
+        val thresholdValue = ThresholdValue()
+        BeanUtils.copyProperties(thresholdValueVo, thresholdValue)
+        val example = Example(ThresholdValue::class.java).apply {
+            createCriteria().andEqualTo("obdVin", thresholdValue.obdVin)
+        }
+        return obdThresholdValueMapper.updateByExample(thresholdValue, example) == 1
+    }
+
+    override fun getByVinCode(vinCode: String): ThresholdValueVo? {
+        val example = Example(ThresholdValue::class.java).apply {
+            createCriteria().andEqualTo("obdVin", vinCode)
+        }
+
+        val result = obdThresholdValueMapper.selectByExample(example)
+
+        if (result.isNotEmpty()) {
+            val vo = ThresholdValueVo()
+            BeanUtils.copyProperties(result[0], vo)
+            return vo
+        }
+
+        return null
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/impl/ObdUserDaoImpl.kt b/src/main/kotlin/com/flightfeather/uav/repository/impl/ObdUserDaoImpl.kt
new file mode 100644
index 0000000..73a00d4
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/impl/ObdUserDaoImpl.kt
@@ -0,0 +1,34 @@
+package com.flightfeather.uav.repository.impl
+
+import com.flightfeather.uav.domain.entity.ObdUser
+import com.flightfeather.uav.domain.mapper.ObdUserMapper
+import com.flightfeather.uav.lightshare.bean.ObdUserVo
+import com.flightfeather.uav.repository.ObdUserRepository
+import org.springframework.beans.BeanUtils
+import org.springframework.stereotype.Repository
+import tk.mybatis.mapper.entity.Example
+
+/**
+ * @author riku
+ * Date: 2019/9/6
+ */
+@Repository
+class ObdUserDaoImpl(val obdUserMapper: ObdUserMapper): ObdUserRepository {
+
+    override fun getUserInfo(userId: String): ObdUserVo? {
+        val example = Example(ObdUser::class.java).apply {
+            createCriteria().andEqualTo("obdUserId", userId)
+        }
+
+        val result = obdUserMapper.selectByExample(example)
+
+        if (result.isNotEmpty()) {
+            val vo = ObdUserVo()
+            BeanUtils.copyProperties(result[0], vo)
+            return vo
+        }
+
+        return null
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/impl/OriginDataDaoImpl.kt b/src/main/kotlin/com/flightfeather/uav/repository/impl/OriginDataDaoImpl.kt
new file mode 100644
index 0000000..427e09e
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/impl/OriginDataDaoImpl.kt
@@ -0,0 +1,29 @@
+package com.flightfeather.uav.repository.impl
+
+import com.flightfeather.uav.domain.entity.OriginData
+import com.flightfeather.uav.domain.mapper.OriginDataMapper
+import com.flightfeather.uav.repository.OriginDataRepository
+import com.flightfeather.uav.socket.bean.ObdPackageData
+import org.springframework.stereotype.Repository
+
+/**
+ * @author riku
+ * Date: 2019/9/17
+ */
+@Repository
+class OriginDataDaoImpl (val originDataMapper: OriginDataMapper): OriginDataRepository {
+
+    override fun saveOriginData(packageData: ObdPackageData, msg: String): Boolean {
+
+        val originData = OriginData().apply {
+            obdDeviceCode = packageData.deviceCode
+            obdTerminalSoftwareVersion = packageData.softwareVersion
+            obdEncryptionWay = packageData.encryptionWay
+            obdCommandUnit = packageData.commandUnit
+            obdContent = msg
+        }
+
+        return originDataMapper.insert(originData) == 1
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/repository/impl/VehicleRepositoryImpl.kt b/src/main/kotlin/com/flightfeather/uav/repository/impl/VehicleRepositoryImpl.kt
new file mode 100644
index 0000000..7d92023
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/repository/impl/VehicleRepositoryImpl.kt
@@ -0,0 +1,24 @@
+package com.flightfeather.uav.repository.impl
+
+import com.flightfeather.uav.domain.entity.DataStream
+import com.flightfeather.uav.domain.entity.VehicleInfo
+import com.flightfeather.uav.domain.mapper.VehicleInfoMapper
+import com.flightfeather.uav.repository.VehicleRepository
+import com.github.pagehelper.PageHelper
+import org.springframework.stereotype.Repository
+
+/**
+ * @author riku
+ * Date: 2019/10/25
+ */
+@Repository
+class VehicleRepositoryImpl(val vehicleInfoMapper: VehicleInfoMapper):VehicleRepository {
+    override fun getVehicleInfo(pageNum: Int?, pageSize: Int?): List<VehicleInfo> {
+
+        //鍒嗛〉
+        val offset = (pageSize?.times(pageNum?.minus(1) ?: 0)) ?: 0
+        PageHelper.offsetPage<DataStream>(offset, pageSize ?: 10)
+
+        return vehicleInfoMapper.selectAll()
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/DeviceSession.kt b/src/main/kotlin/com/flightfeather/uav/socket/DeviceSession.kt
new file mode 100644
index 0000000..1bc9472
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/DeviceSession.kt
@@ -0,0 +1,29 @@
+package com.flightfeather.uav.socket
+
+import io.netty.channel.ChannelHandlerContext
+import java.util.concurrent.ConcurrentHashMap
+
+/**
+ * 鐢ㄤ簬淇濆瓨杩炴帴鐨勮澶囧強瀵瑰簲鐨剆ession閫氶亾
+ * Date: 2019.8.27
+ * @author riku
+ */
+class DeviceSession {
+
+    companion object{
+        private val deviceMap = ConcurrentHashMap<String, ChannelHandlerContext?>()
+
+        fun saveDevice(deviceCode: String?, channel: ChannelHandlerContext?) {
+            deviceCode?.let {
+                deviceMap.put(deviceCode, channel)
+            }
+        }
+
+        fun getDevice(deviceCode: String?): ChannelHandlerContext? {
+            return if (deviceMap.containsKey(deviceCode))
+                deviceMap[deviceCode]
+            else
+                null
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/MessageManager.kt b/src/main/kotlin/com/flightfeather/uav/socket/MessageManager.kt
new file mode 100644
index 0000000..51ad90d
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/MessageManager.kt
@@ -0,0 +1,205 @@
+package com.flightfeather.uav.socket
+
+import com.flightfeather.uav.common.utils.FileUtil
+import com.flightfeather.uav.repository.*
+import com.flightfeather.uav.socket.bean.EngineDataStream
+import com.flightfeather.uav.socket.bean.ObdInfo
+import com.flightfeather.uav.socket.bean.ObdPackageData
+import com.flightfeather.uav.socket.bean.SupplementDataStream
+import com.flightfeather.uav.socket.decoder.VehicleDataDecoder
+import com.flightfeather.uav.socket.decoder.impl.DataPackageDecoderImpl
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+import io.netty.buffer.Unpooled
+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 MessageManager{
+
+    companion object{
+        private lateinit var instance: MessageManager
+    }
+
+    @Autowired
+    lateinit var obdDataRepository: ObdDataRepository
+    @Autowired
+    lateinit var originDataRepository: OriginDataRepository
+    @Autowired
+    lateinit var obdInfoRepository: ObdInfoRepository
+    @Autowired
+    lateinit var dataStreamRepository: DataStreamRepository
+    @Autowired
+    lateinit var carLogoutRepository: CarLogoutRepository
+    @Autowired
+    lateinit var carLoginRepository: CarLoginRepository
+
+    val vehicleDataDecoder = VehicleDataDecoder()
+    val dataPackageDecoder = DataPackageDecoderImpl()
+
+    @PostConstruct
+    fun init() {
+        instance = this
+        instance.obdDataRepository = this.obdDataRepository
+        instance.originDataRepository = this.originDataRepository
+        instance.obdInfoRepository = this.obdInfoRepository
+        instance.dataStreamRepository = this.dataStreamRepository
+        instance.carLogoutRepository = this.carLogoutRepository
+        instance.carLoginRepository = this.carLoginRepository
+    }
+
+    fun dealStringMsg(msg: String, ctx: ChannelHandlerContext?) {
+        //瑙e寘
+        val packageData = vehicleDataDecoder.decode(msg)
+
+        saveToTxt(msg)
+
+        val isCommand = command(packageData, ctx)
+
+        if (isCommand) {
+            println("------杩滅▼鎺у埗鎸囦护 [${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}]")
+        } else {
+            if (bccCheck(msg)) {
+                //淇濆瓨
+                DeviceSession.saveDevice(packageData.deviceCode, ctx)
+                saveToDataBase(packageData, msg)
+            } else {
+                println("------鏁版嵁BCC鏍¢獙澶辫触锛岃垗寮� [${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}]")
+            }
+        }
+    }
+
+    /**
+     * 淇濆瓨鑷硉xt鏂囨湰
+     */
+    fun saveToTxt(msg: String) {
+        val data = "[${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}]data=> $msg"
+        FileUtil.instance?.saveObdData(data)
+    }
+
+    /**
+     * 淇濆瓨鑷虫暟鎹簱
+     */
+    fun saveToDataBase(packageData: ObdPackageData, msg: String) {
+//        instance.obdDataRepository.saveObdData(packageData)
+        instance.originDataRepository.saveOriginData(packageData, msg)
+        when (packageData.commandUnit) {
+            ObdCommandUnit.CarRegister.value -> instance.carLoginRepository.saveCarLogin(packageData)
+            ObdCommandUnit.RealTimeData.value,
+            ObdCommandUnit.ReplacementData.value -> {
+                var done = false
+                for (i in 0 until packageData.dataUnit.size) {
+                    when (packageData.dataUnit[i]) {
+                        is ObdInfo -> instance.obdInfoRepository.saveObdInfo(packageData)
+                        is EngineDataStream,
+                        is SupplementDataStream -> {
+                            instance.dataStreamRepository.saveDataStream(packageData)
+                            done = true
+                        }
+                    }
+                    if (done) break
+                }
+            }
+            ObdCommandUnit.CarLogOut.value-> instance.carLogoutRepository.saveCarLogout(packageData)
+        }
+    }
+
+    /**
+     * BCC锛堝紓鎴栨牎楠岋級
+     */
+    fun bccCheck(msg: String):Boolean {
+        val list = mutableListOf<String>().apply {
+            addAll(dataPackageDecoder.toStringList(msg))
+            //鍘婚櫎2 浣嶈捣濮嬬
+            removeAt(0)
+            removeAt(0)
+        }
+        //鍙栧緱鏁版嵁鍖呬腑鐨刡cc鏍¢獙缁撴灉
+        val oldBcc = list[list.size - 1].toInt(16)
+
+        //鍘婚櫎鏍¢獙缁撴灉
+        list.removeAt(list.size-1)
+
+        //璁$畻bcc鏍¢獙缁撴灉
+        var newBcc = 0x00
+        list.forEach {
+            newBcc = newBcc.xor(it.toInt(16))
+        }
+
+        //杩斿洖鏍¢獙缁撴灉鏄惁姝g‘
+        return oldBcc == newBcc
+    }
+
+    /**
+     * 杩滅▼鎸囦护
+     */
+    fun command(packageData: ObdPackageData, ctx: ChannelHandlerContext?): Boolean {
+        if (packageData.commandUnit == ObdCommandUnit.Update.value) {
+            val channel = DeviceSession.getDevice(packageData.deviceCode)
+            if (channel != null) {
+                val s = getDataPackage(packageData.deviceCode)
+                if (s == null) {
+                    ctx?.writeAndFlush("[${packageData.deviceCode}] 璁惧缂栧彿涓虹┖")
+                } else {
+                    val bytes = encodeToBytes(s)
+                    channel.writeAndFlush(Unpooled.copiedBuffer(bytes))
+                    ctx?.writeAndFlush("[${packageData.deviceCode}] 鎸囦护鍙戦�佹垚鍔�")
+                }
+            } else {
+                ctx?.writeAndFlush("[${packageData.deviceCode}] 璁惧鏈繛鎺ユ垨涓嶅瓨鍦�")
+            }
+            return true
+        } else if (packageData.commandUnit != ObdCommandUnit.CarRegister.value
+                && packageData.commandUnit != ObdCommandUnit.RealTimeData.value
+                && packageData.commandUnit != ObdCommandUnit.ReplacementData.value
+                && packageData.commandUnit != ObdCommandUnit.CarLogOut.value
+                && packageData.commandUnit != ObdCommandUnit.TimeCalibration.value) {
+            ctx?.writeAndFlush("[${packageData.deviceCode}] 鍛戒护涓嶅瓨鍦�")
+
+            return true
+        } else {
+            return false
+        }
+    }
+
+    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()
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/ObdByteDataDecoder.kt b/src/main/kotlin/com/flightfeather/uav/socket/ObdByteDataDecoder.kt
new file mode 100644
index 0000000..8810240
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/ObdByteDataDecoder.kt
@@ -0,0 +1,112 @@
+package com.flightfeather.uav.socket
+
+import io.netty.buffer.ByteBuf
+import io.netty.channel.ChannelHandlerContext
+import io.netty.handler.codec.ByteToMessageDecoder
+import java.lang.StringBuilder
+
+/**
+ * @author riku
+ * Date: 2019/9/16
+ * 鏁版嵁绮樺寘鍒嗗寘瑙g爜鍣�
+ */
+class ObdByteDataDecoder : ByteToMessageDecoder() {
+
+    companion object {
+        const val BASE_LENGTH = 2 + 1 + 17 + 1 + 1 + 2 + 0 + 1
+        const val HEAD = 0x23.toByte()
+    }
+
+    override fun decode(p0: ChannelHandlerContext?, p1: ByteBuf?, p2: MutableList<Any>?) {
+
+        val dataList = mutableListOf<Byte>()
+
+        p1?.let {
+            // 鍙闀垮害蹇呴』澶т簬鍩烘湰闀垮害
+            if (it.readableBytes() >= BASE_LENGTH) {
+                // 闃叉socket瀛楄妭娴佹敾鍑�
+                // 闃叉锛屽鎴风浼犳潵鐨勬暟鎹繃澶�
+                if (it.readableBytes() > 2048) {
+                    it.skipBytes(it.readableBytes())
+                }
+                // 璁板綍鍖呭ご寮�濮嬬殑index
+                var beginReader = 0
+
+                while (true) {
+                    // 鑾峰彇鍖呭ご寮�濮嬬殑index
+                    beginReader = it.readerIndex()
+                    // 鏍囪鍖呭ご寮�濮嬬殑index
+                    it.markReaderIndex()
+                    // 璇诲埌浜嗗崗璁殑寮�濮嬫爣蹇楋紝缁撴潫while寰幆
+                    val b = ByteArray(2)
+                    it.readBytes(b)
+                    if (b[0] == HEAD && b[1] == HEAD) {
+                        dataList.add(b[0])
+                        dataList.add(b[1])
+                        break
+                    }
+
+                    // 鏈鍒板寘澶达紝閲嶇疆鍒颁箣鍓嶈褰曠殑鍖呭ご寮�濮嬩綅缃�
+                    // 鐣ヨ繃1涓瓧鑺傚悗锛屽啀寰幆寮�濮嬭鍙�
+                    it.resetReaderIndex()
+                    it.readByte()
+
+                    //褰撴暟鎹寘闀垮害涓嶈冻鏃讹紝绔嬪埢缁撴潫锛岀瓑寰呭悗缁暟鎹埌杈�
+                    if (it.readableBytes() < BASE_LENGTH) {
+                        return
+                    }
+                }
+
+                ByteArray(1 + 17 + 1 + 1).apply {
+                    it.readBytes(this)
+                }.forEach {b ->
+                    dataList.add(b)
+                }
+
+                //鏁版嵁鍗曞厓鐨勯暱搴�
+                val length = getDataUnitLength(it, dataList)
+                // 鍒ゆ柇璇锋眰鏁版嵁鍗曞厓鏁版嵁鍙�1涓瓧鑺傜殑鏍¢獙鐮佹槸鍚﹀埌榻�
+                if (it.readableBytes() < length + 1) {
+                    // 杩樺師璇绘寚閽�
+                    it.readerIndex(beginReader)
+                    return
+                }
+
+                //璇诲彇鏁版嵁鍗曞厓鍜屾牎楠岀爜鏁版嵁
+                ByteArray(length + 1).apply {
+                    it.readBytes(this)
+                }.forEach {b ->
+                    dataList.add(b)
+                }
+
+                p2?.add(dataList.toByteArray())
+
+            }
+        }
+    }
+
+    /**
+     * 鑾峰彇鏁版嵁鍗曞厓闀垮害骞跺皢鍏舵坊鍔犺嚦缁撴灉鍒楄〃涓�
+     */
+    private fun getDataUnitLength(p1: ByteBuf, dataList: MutableList<Byte>): Int {
+        val sb = StringBuilder()
+
+        ByteArray(2).apply {
+            p1.readBytes(this)
+        }.forEach { b ->
+            var a = 0
+            a = if (b < 0) {
+                b + 256
+            } else {
+                b.toInt()
+            }
+
+            sb.append(a.toString(16))
+
+            dataList.add(b)
+        }
+
+        return sb.toString().toInt(16)
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/ServerHandler.kt b/src/main/kotlin/com/flightfeather/uav/socket/ServerHandler.kt
new file mode 100644
index 0000000..8c08a82
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/ServerHandler.kt
@@ -0,0 +1,70 @@
+package com.flightfeather.uav.socket
+
+import io.netty.channel.ChannelHandlerContext
+import io.netty.channel.ChannelInboundHandlerAdapter
+import io.netty.util.AttributeKey
+import java.lang.StringBuilder
+import java.text.SimpleDateFormat
+import java.util.*
+
+
+class ServerHandler : ChannelInboundHandlerAdapter() {
+
+    val attributeKey = AttributeKey.valueOf<String>("deviceCode")
+
+    override fun channelRegistered(ctx: ChannelHandlerContext?) {
+        super.channelRegistered(ctx)
+        println("------绔彛鏈塈P杩炴帴锛歔ip:${ctx?.channel()?.remoteAddress()}] ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}")
+//        ctx?.fireChannelActive()
+    }
+
+    override fun channelActive(ctx: ChannelHandlerContext?) {
+        println("------绔彛鏈塈P婵�娲伙細[ip:${ctx?.channel()?.remoteAddress()}] ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}")
+        super.channelActive(ctx)
+    }
+
+    override fun channelRead(ctx: ChannelHandlerContext?, msg: Any?) {
+        super.channelRead(ctx, msg)
+
+        val sb = StringBuilder()
+
+        if (msg is ByteArray) {
+            println("------鏀跺埌鐨勫師濮嬫暟鎹細[ip:${ctx?.channel()?.remoteAddress()}] ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}")
+            msg.forEach {
+                var a = 0
+                a = if (it < 0) {
+                    it + 256
+                } else {
+                    it.toInt()
+                }
+                val s = if (a < 16) {
+                    "0${a.toString(16)}"
+                } else {
+                    a.toString(16)
+                }
+                print("$s ")
+                sb.append(s).append(" ")
+            }
+            sb.deleteCharAt(sb.length - 1)
+        }
+        val str = sb.toString()
+        if (str.isNotEmpty()) {
+            MessageManager().dealStringMsg(str, ctx)
+        }
+
+    }
+
+    override fun channelReadComplete(ctx: ChannelHandlerContext?) {
+        super.channelReadComplete(ctx)
+    }
+
+    override fun channelInactive(ctx: ChannelHandlerContext?) {
+        println("------绔彛鏈塈P涓嶆椿鍔細[ip:${ctx?.channel()?.remoteAddress()}] ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}")
+        super.channelInactive(ctx)
+    }
+
+    override fun exceptionCaught(ctx: ChannelHandlerContext?, cause: Throwable?) {
+        cause?.printStackTrace()
+        ctx?.close()
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/SocketServerClient.kt b/src/main/kotlin/com/flightfeather/uav/socket/SocketServerClient.kt
new file mode 100644
index 0000000..3baeaa1
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/SocketServerClient.kt
@@ -0,0 +1,55 @@
+package com.flightfeather.uav.socket
+
+import io.netty.bootstrap.ServerBootstrap
+import io.netty.channel.ChannelInitializer
+import io.netty.channel.ChannelOption
+import io.netty.channel.nio.NioEventLoopGroup
+import io.netty.channel.socket.nio.NioServerSocketChannel
+import io.netty.channel.socket.nio.NioSocketChannel
+import io.netty.handler.codec.string.StringEncoder
+import java.nio.charset.Charset
+
+/**
+ * socket闀胯繛鎺ユ湇鍔$
+ * 2019.8.26
+ * @author riku
+ */
+class SocketServerClient {
+
+    private val bossGroup = NioEventLoopGroup()
+    private val workerGroup = NioEventLoopGroup()
+
+    fun startServer(port: Int) {
+        initialize()?.bind(port)?.sync()
+    }
+
+    fun stopServer() {
+        bossGroup.shutdownGracefully()
+        workerGroup.shutdownGracefully()
+    }
+
+    private fun initialize(): ServerBootstrap? {
+
+        try {
+            return ServerBootstrap()
+                    .group(bossGroup, workerGroup)
+                    .channel(NioServerSocketChannel::class.java)
+                    .option(ChannelOption.SO_BACKLOG, 128)
+                    .childOption(ChannelOption.SO_KEEPALIVE, true)
+                    .childOption(ChannelOption.TCP_NODELAY, true)
+                    .childHandler(object : ChannelInitializer<NioSocketChannel>() {
+                        override fun initChannel(p0: NioSocketChannel?) {
+                            p0?.pipeline()
+//                                    ?.addLast("decoder", StringDecoder())
+                                    ?.addLast(ObdByteDataDecoder())
+                                    ?.addLast("encoder", StringEncoder(Charset.forName("UTF-8")))
+                                    ?.addLast(ServerHandler())
+                        }
+                    })
+        } catch (e: Throwable) {
+            e.printStackTrace()
+        }
+
+        return null
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/bean/CarLogOutData.kt b/src/main/kotlin/com/flightfeather/uav/socket/bean/CarLogOutData.kt
new file mode 100644
index 0000000..6ff5c06
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/bean/CarLogOutData.kt
@@ -0,0 +1,19 @@
+package com.flightfeather.uav.socket.bean
+
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/12
+ * 杞﹁締鐧诲嚭淇℃伅
+ * 鏁版嵁绫诲瀷 @see [ObdCommandUnit.CarLogOut]
+ *
+ * 鏁版嵁琛ㄧず鍐呭                   闀垮害锛堝瓧鑺傦級                  鏁版嵁绫诲瀷                    鎻忚堪鍙婅姹�
+ * 鐧诲嚭鏃堕棿                             6                                   BYTE[6]                   鏃堕棿鍧囧簲閲囩敤 GMT+8 鏃堕棿锛屾椂闂村畾涔夌鍚� GB/T32960.3-2016 绗� 6.4 鏉$殑瑕佹眰
+ * 鐧诲嚭娴佹按鍙�                          2                                  WORD                      鐧诲嚭娴佹按鍙蜂笌褰撴鐧诲叆娴佹按鍙蜂竴鑷淬�侤see [CarRegisterData]
+ */
+class CarLogOutData(
+        time: Date?,
+        serialNum: Int?
+): DataUnit(time, serialNum)
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/bean/CarRegisterData.kt b/src/main/kotlin/com/flightfeather/uav/socket/bean/CarRegisterData.kt
new file mode 100644
index 0000000..2f6d2c1
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/bean/CarRegisterData.kt
@@ -0,0 +1,22 @@
+package com.flightfeather.uav.socket.bean
+
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/12
+ *
+ * 杞﹁締鐧诲叆鏁版嵁鏍煎紡
+ * 鏁版嵁绫诲瀷 @see [ObdCommandUnit.CarRegister]
+ *
+ * 璧峰瀛楄妭        鍐呭                               鎻忚堪
+ * 0                    鏁版嵁閲囬泦鏃堕棿                 鏃堕棿鍧囧簲閲囩敤 GMT+8 鏃堕棿锛屾椂闂村畾涔夌鍚� GB/T32960.3-2016 绗� 6.4 鏉$殑瑕佹眰
+ * 6                    鐧诲叆娴佹按鍙�                   杞﹁浇缁堢姣忕櫥鍏ヤ竴娆★紝鐧诲叆娴佹按鍙疯嚜鍔ㄥ姞 1锛屼粠 1寮�濮嬪惊鐜疮鍔狅紝鏈�澶у�间负 65531锛屽惊鐜懆鏈熶负澶┿��
+ * 10                  SIM 鍗″彿                       SIM 鍗� ICCID 鍙凤紙ICCID 搴斾负缁堢浠� SIM 鍗¤幏鍙栫殑鍊硷紝涓嶅簲浜轰负濉啓鎴栦慨鏀癸級銆�
+ */
+class CarRegisterData(
+        time: Date?,
+        serialNum: Int?,
+        var SIMCode: String? = null
+): DataUnit(time, serialNum)
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/bean/DataUnit.kt b/src/main/kotlin/com/flightfeather/uav/socket/bean/DataUnit.kt
new file mode 100644
index 0000000..bbfcd4e
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/bean/DataUnit.kt
@@ -0,0 +1,16 @@
+package com.flightfeather.uav.socket.bean
+
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/12
+ *
+ * 鏁版嵁鍗曞厓
+ * 鏍规嵁鍛戒护鍗曞厓 @see [ObdCommandUnit] 鐨勫垎绫伙紝涓嶅悓绫诲瀷鐨勭粨鏋勪笉鍚岋紝瑙佸悇瀛愮被
+ */
+open class DataUnit(
+        var time: Date?,
+        var serialNum: Int?
+)
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/bean/EngineDataStream.kt b/src/main/kotlin/com/flightfeather/uav/socket/bean/EngineDataStream.kt
new file mode 100644
index 0000000..32027b3
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/bean/EngineDataStream.kt
@@ -0,0 +1,35 @@
+package com.flightfeather.uav.socket.bean
+
+import com.flightfeather.uav.socket.eunm.ObdDataType
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/15
+ * 瀹炴椂淇℃伅[RealTimeData] 涓殑鍙戝姩鏈烘暟鎹祦
+ * 鏁版嵁绫诲瀷 @see [ObdDataType.EngineDataFlow]
+ */
+class EngineDataStream(
+        time: Date?,
+        serialNum: Int?
+) : RealTimeData(time, serialNum) {
+    var obdSpeed: Double? = null
+    var obdAirPressure: Double? = null
+    var obdEngineTorque: Double? = null
+    var obdFrictionTorque: Double? = null
+    var obdEngineRpm: Double? = null
+    var obdEngineFuelFlow: Double? = null
+    var obdScrUpstreamNox: Double? = null
+    var obdScrDownstreamNox: Double? = null
+    var obdRemainReactant: Double? = null
+    var obdAirInput: Double? = null
+    var obdScrInputTemp: Double? = null
+    var obdScrOutputTemp: Double? = null
+    var obdDpf: Double? = null
+    var obdEngineCoolantTemp: Double? = null
+    var obdFuelLevel: Double? = null
+    var obdLocationStatus: Int? = null
+    var obdLong: Double? = null
+    var obdLat: Double? = null
+    var obdTotalMileage: Double? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/bean/ObdInfo.kt b/src/main/kotlin/com/flightfeather/uav/socket/bean/ObdInfo.kt
new file mode 100644
index 0000000..f0eedb5
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/bean/ObdInfo.kt
@@ -0,0 +1,26 @@
+package com.flightfeather.uav.socket.bean
+
+import com.flightfeather.uav.socket.eunm.ObdDataType
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/15
+ * 瀹炴椂淇℃伅[RealTimeData] 涓殑obd鏁版嵁
+ * 鏁版嵁绫诲瀷 @see [ObdDataType.ObdData]
+ */
+class ObdInfo(
+        time: Date?,
+        serialNum: Int?
+) : RealTimeData(time, serialNum) {
+    var obdProtocol: Int? = null
+    var obdMil: Int? = null
+    var diagnosisSupportStatus: String? = null//璇婃柇鏀寔鐘舵��
+    var diagnosisReadyStatus: String? = null//璇婃柇灏辩华鐘舵��
+    var obdVin: String? = null
+    var obdCrn: String? = null//杞欢鏍囧畾璇嗗埆鍙�
+    var obdCvn: String? = null//鏍囧畾楠岃瘉鐮�
+    var iupr:String?=null//瀹氫箟鍙傝�� SAE J 1979-DA 琛� G11
+    var obdFaultCodeNum: Int? = null//鏁呴殰鐮佹�绘暟: 鏈夋晥鍊艰寖鍥达細0~253锛屸��0xFE鈥濊〃绀烘棤鏁堛��
+    var obdFaultCode: String? = null//鏁呴殰鐮佷俊鎭垪琛�: 姣忎釜鏁呴殰鐮佷负鍥涘瓧鑺傦紝鍙寜鏁呴殰瀹為檯椤哄簭杩涜鎺掑簭
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/bean/ObdPackageData.kt b/src/main/kotlin/com/flightfeather/uav/socket/bean/ObdPackageData.kt
new file mode 100644
index 0000000..7b53378
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/bean/ObdPackageData.kt
@@ -0,0 +1,40 @@
+package com.flightfeather.uav.socket.bean
+
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+
+/**
+ * @author riku
+ * Date: 2019/9/12
+ * 鏁版嵁鍖呯粨鏋�
+ *
+ * 璧峰瀛楄妭                     瀹氫箟                  鏁版嵁绫诲瀷                        鎻忚堪鍙婅姹�
+ * 0                               璧峰绗�                STRING                       鍥哄畾涓� ASCII 瀛楃鈥�##鈥欙紝鐢ㄢ��0x23锛�0x23鈥濊〃绀�
+ * 2                               鍛戒护鍗曞厓             BYTE                            鍛戒护鍗曞厓瀹氫箟 @see [ObdCommandUnit]
+ * 3                            杞﹁締璇嗗埆鍙�           STRING                        杞﹁締璇嗗埆鐮佹槸璇嗗埆鐨勫敮涓�鏍囪瘑锛岀敱 17 浣嶅瓧鐮佺粍鎴愶紝瀛楃爜搴旂鍚� GB16735 涓� 4.5 鐨勮瀹�
+ * 20                         缁堢杞欢鐗堟湰鍙�       BYTE                           缁堢杞欢鐗堟湰鍙锋湁鏁堝�艰寖鍥� 0~255
+ * 21                           鏁版嵁鍔犲瘑鏂瑰紡         BYTE                           0x01锛氭暟鎹笉鍔犲瘑锛�
+ *                                                                                                  0x02锛氭暟鎹粡杩� RSA 绠楁硶鍔犲瘑锛�
+ *                                                                                                  0x03锛氭暟鎹粡杩囧浗瀵� SM2 绠楁硶鍔犲瘑锛�
+ *                                                                                                  鈥�0xFE鈥濇爣璇嗗紓甯革紝鈥�0xFF鈥濊〃绀烘棤鏁堬紝鍏朵粬棰勭暀
+ * 22                           鏁版嵁鍗曞厓闀垮害          WORD                        鏁版嵁鍗曞厓闀垮害鏄暟鎹崟鍏冪殑鎬诲瓧鑺傛暟锛屾湁鏁堣寖鍥达細0~65531
+ * 24                           鏁版嵁鍗曞厓                                                    瑙佹暟鎹崟鍏冩牸寮忓拰瀹氫箟 @see [DataUnit]
+ * 鍊掓暟绗� 1                   鏍¢獙鐮� BYTE                                             閲囩敤 BCC锛堝紓鎴栨牎楠岋級娉曪紝鏍¢獙鑼冨洿鑱槑鏄熷崟鍏冪殑绗竴涓瓧鑺傚紑濮嬶紝鍚屽悗涓�涓瓧鑺傚紓鎴栵紝鐩村埌鏍¢獙鐮佸墠涓�瀛楄妭涓烘锛屾牎楠岀爜鍗犵敤涓�涓瓧鑺�
+ */
+data class ObdPackageData constructor(
+        //璧峰绗�
+        var head: String? = null,
+        //鍛戒护鍗曞厓
+        var commandUnit: Int? = null,
+        //杞﹁締璇嗗埆鍙�(鎸噊bd鏁版嵁閲囬泦璁惧鐨勭紪鍙�)
+        var deviceCode: String? = null,
+        //缁堢杞欢鐗堟湰鍙�
+        var softwareVersion: Int? = null,
+        //鏁版嵁鍔犲瘑鏂瑰紡
+        var encryptionWay: Int? = null,
+        //鏁版嵁鍗曞厓闀垮害
+        var dataLength: Int? = null,
+        //鏁版嵁鍗曞厓
+        var dataUnit: List<DataUnit>,
+        //鏍¢獙鐮�
+        var checkCode: Int? = null
+)
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/bean/RealTimeData.kt b/src/main/kotlin/com/flightfeather/uav/socket/bean/RealTimeData.kt
new file mode 100644
index 0000000..9e60359
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/bean/RealTimeData.kt
@@ -0,0 +1,26 @@
+package com.flightfeather.uav.socket.bean
+
+import java.util.*
+import com.flightfeather.uav.socket.eunm.ObdDataType
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+
+/**
+ * @author riku
+ * Date: 2019/9/12
+ *
+ * 瀹炴椂淇℃伅
+ * 鏁版嵁绫诲瀷 @see[ObdCommandUnit.RealTimeData]
+ *
+ * 鏁版嵁琛ㄧず鍐呭                          闀垮害锛堝瓧鑺傦級             鏁版嵁绫诲瀷                    鎻忚堪鍙婅姹�
+ * 鏁版嵁閲囬泦鏃堕棿                               6                           BYTE[6]                    鏃堕棿鍧囧簲閲囩敤 GMT+8 鏃堕棿锛屾椂闂村畾涔夌鍚� GB/T32960.3-2016 绗� 6.4 鏉$殑瑕佹眰
+ * 淇℃伅娴佹按鍙�                                   2                           WORD                       浠ュぉ涓哄崟浣嶏紝姣忓寘瀹炴椂淇℃伅娴佹按鍙峰敮涓�锛屼粠 1 寮�濮嬬疮鍔�
+ * 淇℃伅绫诲瀷鏍囧織锛坣锛�                       1                           BYTE                         淇℃伅绫诲瀷鏍囧織 @see [ObdDataType]
+ * 淇℃伅浣擄紙n锛�                                                                                                鏍规嵁淇℃伅绫诲瀷涓嶅悓锛岄暱搴﹀拰鏁版嵁绫诲瀷涓嶅悓
+ * 鈥︹��                                                                                                               鈥︹��
+ * 淇℃伅绫诲瀷鏍囧織锛坢锛�                      1                            BYTE[6]                   淇℃伅绫诲瀷鏍囧織
+ * 淇℃伅浣擄紙m锛�                                                                                               鏍规嵁淇℃伅绫诲瀷涓嶅悓锛岄暱搴﹀拰鏁版嵁绫诲瀷涓嶅悓
+ */
+open class RealTimeData(
+        time: Date?,
+        serialNum: Int?
+) : ReplacementData(time, serialNum)
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/bean/ReplacementData.kt b/src/main/kotlin/com/flightfeather/uav/socket/bean/ReplacementData.kt
new file mode 100644
index 0000000..98d07d0
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/bean/ReplacementData.kt
@@ -0,0 +1,15 @@
+package com.flightfeather.uav.socket.bean
+
+import java.util.*
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+
+/**
+ * @author riku
+ * Date: 2019/9/12
+ * 琛ュ彂淇℃伅涓庡疄鏃朵俊鎭唴瀹逛竴鑷� @see [RealTimeData]
+ * 鏁版嵁绫诲瀷 @see [ObdCommandUnit.ReplacementData]
+ */
+open class ReplacementData (
+        time: Date?,
+        serialNum: Int?
+): DataUnit(time, serialNum)
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/bean/SupplementDataStream.kt b/src/main/kotlin/com/flightfeather/uav/socket/bean/SupplementDataStream.kt
new file mode 100644
index 0000000..55d5103
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/bean/SupplementDataStream.kt
@@ -0,0 +1,59 @@
+package com.flightfeather.uav.socket.bean
+
+import java.util.*
+import com.flightfeather.uav.socket.eunm.ObdDataType
+
+/**
+ * @author riku
+ * Date: 2019/9/15
+ * 琛ュ厖鏁版嵁娴�
+ * 鏁版嵁绫诲瀷 @see [ObdDataType.SupplementDataFlow]
+ *
+ * 璧峰瀛楄妭      鏁版嵁椤�                            鏁版嵁绫诲瀷        鍗曚綅          鎻忚堪鍙婅姹�
+ * 0                 鍙戝姩鏈烘壄鐭╂ā寮�                BYTE                            0锛氳秴閫熷け鏁�
+ *                                                                                                  1锛氳浆閫熸帶鍒�
+ *                                                                                                  2锛氭壄鐭╂帶鍒�
+ *                                                                                                  3锛氳浆閫�/鎵煩鎺у埗
+ * 1                  娌归棬韪忔澘                          BYTE               %           鏁版嵁闀垮害锛�1bytes
+ *                                                                                                  绮惧害锛�0.4%/bit
+ *                                                                                                  鍋忕Щ閲忥細0
+ *                                                                                                  鏁版嵁鑼冨洿锛�0~100%
+ *                                                                                                  鈥�0xFF鈥濊〃绀烘棤鏁�
+ * 2                绱娌硅�楋紙鎬绘补鑰楋級          DWORD           L           鏁版嵁闀垮害锛�4bytes
+ *                                                                                                  绮惧害锛�0.5L per bit
+ *                                                                                                  鍋忕Щ閲忥細0
+ *                                                                                                  鏁版嵁鑼冨洿锛�0~2,105,540,607.5L
+ *                                                                                                  鈥�0xFF,0xFF,0xFF,0xFF鈥濊〃绀烘棤鏁�
+ * 6                  灏跨礌绠辨俯搴�                      BYTE               鈩�          鏁版嵁闀垮害锛�1bytes
+ *                                                                                                  绮惧害锛�1 鈩�/bit
+ *                                                                                                  鍋忕Щ閲忥細-40
+ *                                                                                                  鏁版嵁鑼冨洿锛�-40~210鈩�
+ *                                                                                                  鈥�0xFF鈥濊〃绀烘棤鏁�
+ * 7                   瀹為檯灏跨礌鍠峰皠閲�              DWORD         ml/h       鏁版嵁闀垮害锛�4bytes
+ *                                                                                                  绮惧害锛�0.01 ml/h per bit
+ *                                                                                                  鍋忕Щ閲忥細0
+ *                                                                                                  鏁版嵁鑼冨洿锛�0
+ *                                                                                                  鈥�0xFF,0xFF,0xFF,0xFF鈥濊〃绀烘棤鏁�
+ * 11                   绱灏跨礌娑堣�楋紙鎬诲翱绱犳秷鑰楋級DWORD      g        鏁版嵁闀垮害锛�4bytes
+ *                                                                                                  绮惧害锛�1 g per bit
+ *                                                                                                  鍋忕Щ閲忥細0
+ *                                                                                                  鏁版嵁鑼冨洿锛�0
+ *                                                                                                  鈥�0xFF,0xFF,0xFF,0xFF鈥濊〃绀烘棤鏁�
+ * 15                   DPF 鎺掓皵娓╁害                  WORD             鈩�        鏁版嵁闀垮害锛�2bytes
+ *                                                                                                   绮惧害锛�0.03125 鈩� per bit
+ *                                                                                                   鍋忕Щ閲忥細-273
+ *                                                                                                   鏁版嵁鑼冨洿锛�-273~1734.96875鈩�
+ *                                                                                                   鈥�0xFF,0xFF鈥濊〃绀烘棤鏁�
+ */
+class SupplementDataStream(
+        time: Date?,
+        serialNum: Int?
+) : RealTimeData(time, serialNum) {
+    var obdEngineTorqueMode: Int? = null
+    var obdAcceleratorPedal: Double? = null
+    var obdTotalOilConsumption: Double? = null
+    var obdUreaBoxTemp: Double? = null
+    var obdUreaVolume: Double? = null
+    var obdTotalUreaConsume: Double? = null
+    var obdDpfTemp: Double? = null
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/bean/TimeCalibrationData.kt b/src/main/kotlin/com/flightfeather/uav/socket/bean/TimeCalibrationData.kt
new file mode 100644
index 0000000..8268606
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/bean/TimeCalibrationData.kt
@@ -0,0 +1,16 @@
+package com.flightfeather.uav.socket.bean
+
+import java.util.*
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+/**
+ * @author riku
+ * Date: 2019/9/12
+ *
+ * 杞﹁浇缁堢鏍℃椂鐨勬暟鎹崟鍏冧负绌恒��
+ * 鏁版嵁绫诲瀷 @see [ObdCommandUnit.TimeCalibration]
+ *
+ */
+class TimeCalibrationData(
+        time: Date? = null,
+        serialNum: Int? = null
+) : DataUnit(time, serialNum)
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/decoder/DataPackageDecoder.kt b/src/main/kotlin/com/flightfeather/uav/socket/decoder/DataPackageDecoder.kt
new file mode 100644
index 0000000..1849efa
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/decoder/DataPackageDecoder.kt
@@ -0,0 +1,42 @@
+package com.flightfeather.uav.socket.decoder
+
+import com.flightfeather.uav.socket.bean.DataUnit
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+
+/**
+ * uav 绗竴灞傛暟鎹寘瑙g爜鍣�
+ * @author riku
+ * Date: 2019/9/12
+ *
+ * 鏁版嵁绗竴灞傜粨鏋勫畾涔夊涓嬶細
+ * 璧峰瀛楄妭         瀹氫箟
+ * 0                    璧峰绗�
+ * 2                    鍛戒护鍗曞厓  绫诲瀷@see [ObdCommandUnit]
+ * 3                    杞﹁締璇嗗埆鍙�
+ * 4                    缁堢杞欢鐗堟湰鍙�
+ * 21                   鏁版嵁鍔犲瘑鏂瑰紡
+ * 22                   鏁版嵁鍗曞厓闀垮害
+ * 24                   鏁版嵁鍗曞厓  瑙g爜鍣ˊsee [DataUnitDecoder]
+ * 鍊掓暟绗�1           鏍¢獙鐮�
+ */
+interface DataPackageDecoder {
+
+    fun getHead(b: List<String>): String?
+
+    fun getCommandUnit(b: List<String>): Int?
+
+    fun getVinCode(b: List<String>): String?
+
+    fun getSoftwareVersion(b: List<String>): Int?
+
+    fun getEncryptionWay(b: List<String>): Int?
+
+    fun getDataLength(b: List<String>): Int
+
+    fun getDataUnit(b: List<String>): List<DataUnit>
+
+    fun getCheckCode(b: List<String>): Int?
+
+    fun toStringList(msg: String): List<String>
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/decoder/DataUnitDecoder.kt b/src/main/kotlin/com/flightfeather/uav/socket/decoder/DataUnitDecoder.kt
new file mode 100644
index 0000000..a2fb584
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/decoder/DataUnitDecoder.kt
@@ -0,0 +1,36 @@
+package com.flightfeather.uav.socket.decoder
+
+import com.flightfeather.uav.socket.bean.*
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+import java.util.*
+
+/**
+ * uav 绗簩灞傛暟鎹崟鍏冭В鐮佸櫒
+ * @author riku
+ * Date: 2019/9/12
+ *
+ * 鏁版嵁鍗曞厓鎸夌収鍛戒护鍗曞厓鐨勭被鍨嬪叡鏈変互涓嬪嚑绉嶇被鍨嬶細
+ * 鍛戒护鍗曞厓 @see [ObdCommandUnit]
+ * 缂栫爜(byte)        瀹氫箟
+ * 0x01                 杞﹁締鐧诲叆
+ * 0x02                 瀹炴椂淇℃伅涓婃姤
+ * 0x03                 琛ュ彂淇℃伅涓婃姤
+ * 0x04                 杞﹁締鐧诲嚭
+ * 0x05                 缁堢鏍℃椂
+ * 0x06~0x7f       涓婅鏁版嵁绯荤粺棰勭暀
+ */
+interface DataUnitDecoder {
+
+    fun getCarRegisterData(b: List<String>): List<CarRegisterData>
+
+    fun getRealTimeData(b: List<String>): List<RealTimeData>
+
+    fun getReplacementData(b: List<String>): List<ReplacementData>
+
+    fun getCarLogOutData(b: List<String>): List<CarLogOutData>
+
+    fun getTimeCalibrationData(b: List<String>): List<TimeCalibrationData>
+
+    fun decodeDataTime(b: List<String>): Date?
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/decoder/RealTimeDataDecoder.kt b/src/main/kotlin/com/flightfeather/uav/socket/decoder/RealTimeDataDecoder.kt
new file mode 100644
index 0000000..dca173c
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/decoder/RealTimeDataDecoder.kt
@@ -0,0 +1,26 @@
+package com.flightfeather.uav.socket.decoder
+
+import com.flightfeather.uav.socket.bean.*
+import com.flightfeather.uav.socket.eunm.ObdDataType
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/15
+ * 鏁版嵁鍗曞厓[DataUnit]涓紝绫诲瀷涓哄疄鏃朵俊鎭痆RealTimeData]鐨勮В鐮佸櫒
+ * 鍏跺垎绫� @see [ObdDataType]
+ */
+interface RealTimeDataDecoder {
+
+    fun getObdData(time: Date?, serialNum: Int, b: List<String>): ObdInfo?
+
+    fun getEngineDataStream(time: Date?, serialNum: Int, b: List<String>): EngineDataStream?
+
+    fun getSupplementDataStream(time: Date?, serialNum: Int, b: List<String>): SupplementDataStream?
+
+    /**
+     * 鏍规嵁浼犲叆鐨勫垪琛紝榛樿绗竴浣嶄负 [ObdDataType]锛岃繑鍥炲搴旂殑鏁版嵁鍒楄〃
+     */
+    fun getDataListByDataType(list: List<String>): MutableList<String>
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/decoder/VehicleDataDecoder.kt b/src/main/kotlin/com/flightfeather/uav/socket/decoder/VehicleDataDecoder.kt
new file mode 100644
index 0000000..17eda1c
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/decoder/VehicleDataDecoder.kt
@@ -0,0 +1,32 @@
+package com.flightfeather.uav.socket.decoder
+
+import com.flightfeather.uav.socket.bean.ObdPackageData
+import com.flightfeather.uav.socket.decoder.impl.DataPackageDecoderImpl
+
+/**
+ * 杞﹁締 uav 鏁版嵁瑙g爜鍣�
+ * @author riku
+ * Date: 2019/9/12
+ */
+class VehicleDataDecoder {
+
+    private val dataPackageDecoder: DataPackageDecoder = DataPackageDecoderImpl()
+
+    fun decode(msg: String): ObdPackageData {
+        val list = dataPackageDecoder.toStringList(msg)
+        dataPackageDecoder.run {
+            return ObdPackageData(
+                    getHead(list),
+                    getCommandUnit(list),
+                    getVinCode(list),
+                    getSoftwareVersion(list),
+                    getEncryptionWay(list),
+                    getDataLength(list),
+                    getDataUnit(list),
+                    getCheckCode(list)
+            )
+        }
+    }
+
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/decoder/impl/DataPackageDecoderImpl.kt b/src/main/kotlin/com/flightfeather/uav/socket/decoder/impl/DataPackageDecoderImpl.kt
new file mode 100644
index 0000000..cb41fb8
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/decoder/impl/DataPackageDecoderImpl.kt
@@ -0,0 +1,98 @@
+package com.flightfeather.uav.socket.decoder.impl
+
+import com.flightfeather.uav.socket.bean.DataUnit
+import com.flightfeather.uav.socket.decoder.DataPackageDecoder
+import com.flightfeather.uav.socket.decoder.DataUnitDecoder
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+
+/**
+ * @author riku
+ * Date: 2019/9/12
+ */
+class DataPackageDecoderImpl : DataPackageDecoder {
+
+    private val dataUnitDecoder: DataUnitDecoder = DataUnitDecoderImpl()
+
+    // 鎺ユ敹鍒扮殑瀛楃涓叉槸byte杞爜鍓嶇殑锛屽叾灏辫〃绀哄瓧绗︾殑ASCII鐮侊紱
+
+    override fun getHead(b: List<String>): String? {
+        return if (b.size >= 2) {
+            "${b[0]}${b[1]}"
+        } else {
+            null
+        }
+    }
+
+    override fun getCommandUnit(b: List<String>): Int? = if (b.size >= 3) {
+        b[2].toIntOrNull(16)
+    } else {
+        null
+    }
+
+    override fun getVinCode(b: List<String>): String? {
+        if (b.size < 20) return null
+
+        //fixme 搴旇鏄渶瑕佸皢b褰撲綔ASCII鐮侊紝鍐嶈幏鍙栬浆鎹㈠悗鐨勫瓧绗︿覆
+        val s = StringBuilder()
+
+        for (i in 3..19) {
+            s.append(b[i].toIntOrNull(16)?.toChar())
+        }
+
+        return s.toString()
+    }
+
+    override fun getSoftwareVersion(b: List<String>): Int? = if (b.size >= 21) {
+        b[20].toIntOrNull(16)
+    } else {
+        null
+    }
+
+    override fun getEncryptionWay(b: List<String>): Int? = if (b.size >= 21) {
+        b[21].toIntOrNull(16)
+    } else {
+        null
+    }
+
+    override fun getDataLength(b: List<String>): Int {
+        if (b.size < 24) return 0
+
+        val hexNum = "${b[22]}${b[23]}"
+
+        return hexNum.toIntOrNull(16) ?: 0
+    }
+
+    override fun getDataUnit(b: List<String>): List<DataUnit> {
+        if (getDataLength(b) == 0 || b.size < 26) {
+            return emptyList()
+        }
+
+        val unit = mutableListOf<String>()
+        for (i in 24..b.size - 2) {
+            unit.add(b[i])
+        }
+        dataUnitDecoder.run {
+            return when (getCommandUnit(b)) {
+                ObdCommandUnit.CarRegister.value -> getCarRegisterData(unit)
+                ObdCommandUnit.RealTimeData.value -> getRealTimeData(unit)
+                ObdCommandUnit.ReplacementData.value -> getReplacementData(unit)
+                ObdCommandUnit.CarLogOut.value -> getCarLogOutData(unit)
+                ObdCommandUnit.TimeCalibration.value -> getTimeCalibrationData(unit)
+                else -> emptyList()
+            }
+        }
+    }
+
+    override fun getCheckCode(b: List<String>): Int? {
+        return if (b.isNotEmpty()) {
+            b[b.size - 1].toIntOrNull(16)
+        } else {
+            null
+        }
+    }
+
+    override fun toStringList(msg: String): List<String> {
+        return msg.split(" ")
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/decoder/impl/DataUnitDecoderImpl.kt b/src/main/kotlin/com/flightfeather/uav/socket/decoder/impl/DataUnitDecoderImpl.kt
new file mode 100644
index 0000000..ef8f26d
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/decoder/impl/DataUnitDecoderImpl.kt
@@ -0,0 +1,127 @@
+package com.flightfeather.uav.socket.decoder.impl
+
+import com.flightfeather.uav.socket.bean.*
+import com.flightfeather.uav.socket.decoder.DataUnitDecoder
+import com.flightfeather.uav.socket.decoder.RealTimeDataDecoder
+import com.flightfeather.uav.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
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/decoder/impl/RealTimeDataDecoderImpl.kt b/src/main/kotlin/com/flightfeather/uav/socket/decoder/impl/RealTimeDataDecoderImpl.kt
new file mode 100644
index 0000000..690239f
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/decoder/impl/RealTimeDataDecoderImpl.kt
@@ -0,0 +1,185 @@
+package com.flightfeather.uav.socket.decoder.impl
+
+import com.flightfeather.uav.common.INVALID_DATA_4_BYTE
+import com.flightfeather.uav.socket.bean.EngineDataStream
+import com.flightfeather.uav.socket.bean.ObdInfo
+import com.flightfeather.uav.socket.bean.SupplementDataStream
+import com.flightfeather.uav.socket.decoder.RealTimeDataDecoder
+import com.flightfeather.uav.socket.eunm.ObdDataType
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/15
+ */
+class RealTimeDataDecoderImpl : RealTimeDataDecoder {
+    override fun getObdData(time: Date?, serialNum: Int, b: List<String>): ObdInfo? {
+        val dataList = mutableListOf<String>().apply { addAll(b) }
+        if (b.isNotEmpty()) {
+            //鍘婚櫎 淇℃伅绫诲瀷鏍囧織
+            dataList.removeAt(0)
+        }
+        if (dataList.size >= 96) {
+            val vin = StringBuilder()
+            for (i in 6..22) {
+                vin.append(dataList[i].toIntOrNull(16)?.toChar())
+            }
+            val softwareCode = StringBuilder()
+            for (i in 23..40) {
+                softwareCode.append(dataList[i].toIntOrNull(16)?.toChar())
+            }
+            val cvn = StringBuilder()
+            for (i in 41..58) {
+                cvn.append(dataList[i].toIntOrNull(16)?.toChar())
+            }
+            val IUPR = StringBuilder()
+            for (i in 59..94) {
+                //todo 2019.9.15 鍥犳殏涓嶆竻妤氭牸寮忎笌鍚箟锛岀洿鎺ヤ繚瀛�
+                IUPR.append(dataList[i])
+            }
+            var faultCodeNum = dataList[95].toIntOrNull() ?: 0
+            val faultCode = StringBuilder()
+            if (faultCodeNum < 0 || faultCodeNum > 253) {
+                faultCodeNum = 254//浠h〃鏃犳晥
+            } else {
+                for (i in 96..(95 + 4 * faultCodeNum)) {
+                    faultCode.append(dataList[i])
+                }
+            }
+
+            return ObdInfo(time, serialNum).apply {
+                obdProtocol = dataList[0].toIntOrNull(16)
+                obdMil = dataList[1].toIntOrNull(16)
+                diagnosisSupportStatus = "${dataList[2]}${dataList[3]}".toIntOrNull(16)?.toString(2)
+                diagnosisReadyStatus = "${dataList[4]}${dataList[5]}".toIntOrNull(16)?.toString(2)
+                obdVin = vin.toString()
+                obdCrn = softwareCode.toString()
+                obdCvn = cvn.toString()
+                this.iupr = IUPR.toString()
+                obdFaultCodeNum = faultCodeNum
+                obdFaultCode = faultCode.toString()
+            }
+        } else {
+            return null
+        }
+    }
+
+    override fun getEngineDataStream(time: Date?, serialNum: Int, b: List<String>): EngineDataStream? {
+        val dataList = mutableListOf<String>().apply { addAll(b) }
+        if (b.isNotEmpty()) {
+            //鍘婚櫎 淇℃伅绫诲瀷鏍囧織
+            dataList.removeAt(0)
+        }
+
+        return if (dataList.size >= 37) {
+             EngineDataStream(time, serialNum).apply {
+                obdSpeed = "${dataList[0]}${dataList[1]}".toIntOrNull(16)?.toDouble()?.div(256)
+                obdAirPressure = dataList[2].toIntOrNull(16)?.toDouble()?.times(0.5)
+                obdEngineTorque = dataList[3].toIntOrNull(16)?.minus(125)?.toDouble()?.div(100)
+                obdFrictionTorque = dataList[4].toIntOrNull(16)?.minus(125)?.toDouble()?.div(100)
+                obdEngineRpm = "${dataList[5]}${dataList[6]}".toIntOrNull(16)?.toDouble()?.times(0.125)
+                obdEngineFuelFlow = "${dataList[7]}${dataList[8]}".toIntOrNull(16)?.toDouble()?.times(0.05)
+                obdScrUpstreamNox = "${dataList[9]}${dataList[10]}".toIntOrNull(16)?.times(0.05)?.minus(200)
+                obdScrDownstreamNox = "${dataList[11]}${dataList[12]}".toIntOrNull(16)?.times(0.05)?.minus(200)
+                obdRemainReactant = dataList[13].toIntOrNull(16)?.toDouble()?.times(0.4)?.div(100)
+                obdAirInput = "${dataList[14]}${dataList[15]}".toIntOrNull(16)?.toDouble()?.times(0.05)
+                obdScrInputTemp = "${dataList[16]}${dataList[17]}".toIntOrNull(16)?.times(0.03125)?.minus(273)
+                obdScrOutputTemp = "${dataList[18]}${dataList[19]}".toIntOrNull(16)?.times(0.03125)?.minus(273)
+                obdDpf = "${dataList[20]}${dataList[21]}".toIntOrNull(16)?.toDouble()?.times(0.1)
+                obdEngineCoolantTemp = dataList[22].toIntOrNull(16)?.minus(40)?.toDouble()
+                obdFuelLevel = dataList[23].toIntOrNull(16)?.toDouble()?.times(0.4)
+                obdLocationStatus = dataList[24].toIntOrNull(16)
+                 with("${dataList[25]}${dataList[26]}${dataList[27]}${dataList[28]}") {
+                     obdLong = if (toUpperCase() == INVALID_DATA_4_BYTE) { -1.0 } else { toBigIntegerOrNull(16)?.toDouble()?.times(0.000001) }
+                 }
+                 with("${dataList[29]}${dataList[30]}${dataList[31]}${dataList[32]}") {
+                     obdLat = if (toUpperCase() == INVALID_DATA_4_BYTE) { -1.0 } else { toBigIntegerOrNull(16)?.toDouble()?.times(0.000001) }
+                 }
+                 with("${dataList[33]}${dataList[34]}${dataList[35]}${dataList[36]}") {
+                     obdTotalMileage = if (toUpperCase() == INVALID_DATA_4_BYTE) { -1.0 } else { toBigIntegerOrNull(16)?.toDouble()?.times(0.1) }
+                 }
+            }
+        } else {
+            null
+        }
+    }
+
+    override fun getSupplementDataStream(time: Date?, serialNum: Int, b: List<String>): SupplementDataStream? {
+        val dataList = mutableListOf<String>().apply { addAll(b) }
+        if (b.isNotEmpty()) {
+            //鍘婚櫎 淇℃伅绫诲瀷鏍囧織
+            dataList.removeAt(0)
+        }
+
+        return if (dataList.size >= 17) {
+            SupplementDataStream(time, serialNum).apply {
+                obdEngineTorqueMode = dataList[0].toIntOrNull(16)
+                obdAcceleratorPedal = dataList[1].toIntOrNull(16)?.toDouble()?.times(0.4)?.div(100)
+                with("${dataList[2]}${dataList[3]}${dataList[4]}${dataList[5]}") {
+                    obdTotalOilConsumption = if (toUpperCase() == INVALID_DATA_4_BYTE) -1.0 else toBigIntegerOrNull(16)?.toDouble()?.times(0.5)
+                }
+                obdUreaBoxTemp  = dataList[6].toIntOrNull(16)?.toDouble()?.minus(40)
+                with("${dataList[7]}${dataList[8]}${dataList[9]}${dataList[10]}") {
+                    obdUreaVolume = if (toUpperCase() == INVALID_DATA_4_BYTE) -1.0 else toBigIntegerOrNull(16)?.toDouble()?.times(0.01)
+                }
+                with("${dataList[11]}${dataList[12]}${dataList[13]}${dataList[14]}") {
+                    obdTotalUreaConsume = if (toUpperCase() == INVALID_DATA_4_BYTE) -1.0 else toBigIntegerOrNull(16)?.toDouble()
+                }
+                obdDpfTemp  = "${dataList[15]}${dataList[16]}".toIntOrNull(16)?.times(0.03125)?.minus(273)
+            }
+        } else {
+            null
+        }
+    }
+
+    override fun getDataListByDataType(list: List<String>): MutableList<String> {
+        if (list.isEmpty()) return mutableListOf()
+
+        //fixme 2019.9.16 涓嶇绗竴浣嶇殑淇℃伅绫诲瀷鏍囧織鏄惁姝g‘锛岃嚦灏戣繑鍥炰竴涓�硷紝姝ゆ柟娉曞湪淇℃伅浣撶粨鏋勬病鏈変弗鏍兼寜鐓ф爣鍑嗭紝
+        //fixme  鍗冲湪鍚庝竴涓俊鎭被鍨嬫爣蹇楀拰鍓嶄竴涓俊鎭綋涔嬮棿鏈夋棤鏁堝瓧绗︽椂锛岃兘澶熷皢鍏跺拷鐣ワ紝浣嗕笉纭畾杩欑澶勭悊鏂瑰紡鏄惁姝g‘鍜屽繀瑕�
+        val resultList = mutableListOf<String>().apply {
+            add(list[0])
+        }
+
+        when (list[0].toIntOrNull(16)) {
+            ObdDataType.ObdData.value -> {
+
+                if (list.size >= 97) {
+                    //浠庤捣濮嬪瓧鑺� 1 寮�濮嬶紝鍥哄畾鏈�96涓瓧鑺傜殑鏁版嵁
+                    for (i in 1..96) {
+                        resultList.add(list[i])
+                    }
+
+                    val faultCodeNum = list[96].toIntOrNull() ?: 0//鏁呴殰鐮佹�绘暟
+                    //鏍规嵁鏁呴殰鐮佹�绘暟锛屾瘡涓晠闅滅爜4涓瓧鑺傦紝寰楀埌鏁呴殰鐮佹�诲瓧鑺傛暟
+                    if (faultCodeNum in 0..253) {
+                        for (i in 97..(96 + faultCodeNum * 4)) {
+                            resultList.add(list[i])
+                        }
+                    }
+                }
+            }
+            ObdDataType.EngineDataFlow.value -> {
+
+                if (list.size >= 38) {
+                    //浠庤捣濮嬪瓧鑺� 1 寮�濮嬶紝鍥哄畾鏈�37涓瓧鑺傜殑鏁版嵁
+                    for (i in 1..37) {
+                        resultList.add(list[i])
+                    }
+                }
+            }
+            ObdDataType.SupplementDataFlow.value -> {
+
+                if (list.size>= 18) {
+                    //浠庤捣濮嬪瓧鑺� 1 寮�濮嬶紝鍥哄畾鏈�17涓瓧鑺傜殑鏁版嵁
+                    for (i in 1..17) {
+                        resultList.add(list[i])
+                    }
+                }
+            }
+        }
+
+        return resultList
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/eunm/ObdCommandUnit.kt b/src/main/kotlin/com/flightfeather/uav/socket/eunm/ObdCommandUnit.kt
new file mode 100644
index 0000000..1c7dbfe
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/eunm/ObdCommandUnit.kt
@@ -0,0 +1,27 @@
+package com.flightfeather.uav.socket.eunm
+
+import com.flightfeather.uav.socket.bean.*
+
+/**
+ * @author riku
+ * Date: 2019/9/12
+ *
+ * uav 鍛戒护鍗曞厓
+ *
+ * 缂栫爜                   瀹氫箟                     鏂瑰悜
+ * 0x01             杞﹁締鐧诲叆                    涓婅 @see [CarRegisterData]
+ * 0x02            瀹炴椂淇℃伅涓婃姤             涓婅 @see [com.flightfeather.uav.socket.bean.RealTimeData]
+ * 0x03            琛ュ彂淇℃伅涓婃姤             涓婅 @see [com.flightfeather.uav.socket.bean.ReplacementData]
+ * 0x04            杞﹁締鐧诲嚭                    涓婅 @see [CarLogOutData]
+ * 0x05            缁堢鏍℃椂                    涓婅 @see [TimeCalibrationData]
+ * 0x06~0x7F 涓婅鏁版嵁绯荤粺棰勭暀      涓婅
+ * 0x7F            鍥轰欢杩滅▼鏇存柊
+ */
+enum class ObdCommandUnit constructor(val value: Int) {
+    CarRegister(1),
+    RealTimeData(2),
+    ReplacementData(3),
+    CarLogOut(4),
+    TimeCalibration(5),
+    Update(127)
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/eunm/ObdDataType.kt b/src/main/kotlin/com/flightfeather/uav/socket/eunm/ObdDataType.kt
new file mode 100644
index 0000000..725acdd
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/socket/eunm/ObdDataType.kt
@@ -0,0 +1,20 @@
+package com.flightfeather.uav.socket.eunm
+
+import com.flightfeather.uav.socket.bean.*
+/**
+ * @author riku
+ * Date: 2019/9/15
+ *
+ * 瀹炴椂淇℃伅[RealTimeData]鍜岃ˉ鍙戜俊鎭痆ReplacementData] 涓殑鏁版嵁绫诲瀷
+ * 绫诲瀷缂栫爜                     璇存槑
+ * 0x01                           OBD 淇℃伅    @see [com.flightfeather.uav.socket.bean.ObdInfo]
+ * 0x02                          鏁版嵁娴佷俊鎭�  @see[com.flightfeather.uav.socket.bean.EngineDataStream]
+ * 0x03-0x7F                棰勭暀
+ * 0x80                          琛ュ厖鏁版嵁娴�   @see[com.flightfeather.uav.socket.bean.SupplementDataStream]
+ * 0x81~0xFE                鐢ㄦ埛鑷畾涔�
+ */
+enum class ObdDataType constructor(val value: Int){
+    ObdData(1),
+    EngineDataFlow(2),
+    SupplementDataFlow(128)
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/flightfeather/uav/Test.kt b/src/test/kotlin/com/flightfeather/uav/Test.kt
new file mode 100644
index 0000000..d359695
--- /dev/null
+++ b/src/test/kotlin/com/flightfeather/uav/Test.kt
@@ -0,0 +1,150 @@
+package com.flightfeather.uav
+
+import org.junit.Test
+import java.text.SimpleDateFormat
+import java.util.*
+
+/**
+ * @author riku
+ * Date: 2019/9/12
+ */
+class Test {
+
+    @Test
+    fun foo1() {
+        val b = ByteArray(20) {8}
+        val a = 1
+        println(a.toString(2))
+    }
+
+    @Test
+    fun foo2() {
+        val b = ByteArray(2)
+        b[0] = 0x01
+        b[1] = 0x80.toByte()
+
+        println("${b[0].toString(16)}${b[1].toInt()}")
+        println("${b[0]}${b[1]}".toInt(16))
+    }
+
+    @Test
+    fun foo3() {
+        val hexNum = "ff"
+        val length = hexNum.toInt(16)
+        println(length)
+    }
+
+    @Test
+    fun foo4() {
+        val h = "0101"
+        val byte = 0xff
+        val b = h.toInt(16)
+        println(b)
+    }
+
+    @Test
+    fun foo5() {
+        val s = "23 23 30 30 30 30 30 35 33 31 36 30 38 30 31 30 35 33 36"
+        val sb = StringBuilder()
+        val ascii = s.split(" ")
+        ascii.forEach {
+            sb.append(it.toIntOrNull(16)?.toChar())
+        }
+        println(sb.toString())
+    }
+
+    @Test
+    fun foo6() {
+        val cal  = Calendar.getInstance().apply {
+            set(2019, 9, 15, 23, 16, 59)
+        }
+
+        println(SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(cal.time))
+    }
+
+    @Test
+    fun foo7() {
+        val a = "0AAF".toIntOrNull(16)?.toString(2)
+        println(a)
+    }
+
+    @Test
+    fun foo8() {
+        val byte = ByteArray(2)
+        byte[0] = 0x23
+        byte[1] = 0x23
+
+        byte[0].toString(16)
+    }
+
+    @Test
+    fun foo9() {
+        val b = 128.toByte()
+        var a = 0
+        if (b < 0) {
+            a = b + 256
+        } else {
+            a = b.toInt()
+        }
+        println(b.toString(16))
+    }
+
+    @Test
+    fun foo10() {
+        val s = "2 31 37 36 39 31 35 33 31 39 30 39 31 32 30 30 30 36 1 1 0 42 13 9 f 12 33 3b 2 0 8a 1b 0 36 2e 0 23 60 11 b4 0 c8 0 b4 0 0 66 0 0 0 0 0 0 73 0 0 0 b9 4 75 0 2e d8 ed 0 0 0 0 80 0 bc 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"
+        val ascii = s.split(" ")
+        var bcc = 0x00
+        ascii.forEach {
+            bcc = bcc.xor(it.toInt(16))
+        }
+        println(bcc.toString(16))
+    }
+
+    @Test
+    fun foo11() {
+        val b = mutableListOf<String>().apply {
+            add("13")
+            add("09")
+            add("10")
+            add("10")
+            add("2b")
+            add("2f")
+        }
+        if (b.size < 6) {
+            println("null")
+        }
+
+        val year = b[0].toInt(16) + 2000
+        if (year < 2000 || year > 2099) println("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)
+        }
+
+        println(SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(cal.time))
+    }
+
+    @Test
+    fun f0012() {
+        val sb = java.lang.StringBuilder()
+        val byte = ByteArray(2)
+        byte[0] = 0x00
+        byte[1] = 0xBD.toByte()
+        byte.forEach { b ->
+            var a = 0
+            a = if (b < 0) {
+                b + 256
+            } else {
+                b.toInt()
+            }
+
+            sb.append(a.toString(16))
+        }
+
+        println(sb.toString().toInt(16))
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/flightfeather/obd/ObdApplicationTests.kt b/src/test/kotlin/com/flightfeather/uav/UAVApplicationTests.kt
similarity index 83%
rename from src/test/kotlin/com/flightfeather/obd/ObdApplicationTests.kt
rename to src/test/kotlin/com/flightfeather/uav/UAVApplicationTests.kt
index db1a9dc..0f0e75f 100644
--- a/src/test/kotlin/com/flightfeather/obd/ObdApplicationTests.kt
+++ b/src/test/kotlin/com/flightfeather/uav/UAVApplicationTests.kt
@@ -1,8 +1,7 @@
-package com.flightfeather.obd
+package com.flightfeather.uav
 
-import com.flightfeather.obd.domain.mapper.ObdDataMapper
-import com.flightfeather.obd.lightshare.bean.BaseJson
-import com.flightfeather.obd.lightshare.bean.ObdDataVo
+import com.flightfeather.uav.domain.mapper.ObdDataMapper
+import com.flightfeather.uav.lightshare.bean.ObdDataVo
 import com.google.gson.Gson
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -13,7 +12,7 @@
 
 @RunWith(SpringRunner::class)
 @SpringBootTest
-class ObdApplicationTests {
+class UAVApplicationTests {
 
     @Autowired
     lateinit var obdDataMapper: ObdDataMapper
diff --git a/src/test/kotlin/com/flightfeather/uav/socket/MessageManagerTest.kt b/src/test/kotlin/com/flightfeather/uav/socket/MessageManagerTest.kt
new file mode 100644
index 0000000..38b1810
--- /dev/null
+++ b/src/test/kotlin/com/flightfeather/uav/socket/MessageManagerTest.kt
@@ -0,0 +1,18 @@
+package com.flightfeather.uav.socket
+
+import org.junit.Test
+
+/**
+ * @author riku
+ * Date: 2019/9/16
+ */
+class MessageManagerTest {
+
+    private val messageManager = MessageManager()
+
+    @Test
+    fun bccCheck() {
+        val s = "23 23 2 31 37 36 39 31 35 33 31 39 30 39 31 32 30 30 30 36 1 1 0 42 13 9 f 12 34 8 2 0 8b 1c 0 d8 0 0 12 d8 9 6c 0 c8 0 b4 0 0 66 0 0 0 0 0 0 73 0 0 0 b9 4 32 0 2e d8 c4 0 0 0 0 80 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 f6"
+        println(messageManager.bccCheck(s))
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/flightfeather/uav/socket/decoder/VehicleDataDecoderTest.kt b/src/test/kotlin/com/flightfeather/uav/socket/decoder/VehicleDataDecoderTest.kt
new file mode 100644
index 0000000..dcbdc7a
--- /dev/null
+++ b/src/test/kotlin/com/flightfeather/uav/socket/decoder/VehicleDataDecoderTest.kt
@@ -0,0 +1,102 @@
+package com.flightfeather.uav.socket.decoder
+
+import com.flightfeather.uav.domain.entity.ObdData
+import com.flightfeather.uav.socket.bean.*
+import com.flightfeather.uav.socket.eunm.ObdCommandUnit
+import org.junit.Test
+
+/**
+ * @author riku
+ * Date: 2019/9/17
+ */
+class VehicleDataDecoderTest {
+
+    private val vehicleDataDecoder = VehicleDataDecoder()
+
+    @Test
+    fun decode() {
+        val msg = "23 23 02 31 37 36 39 31 35 33 31 39 30 39 31 32 30 30 31 36 01 01 00 40 13 09 17 09 05 29 00 cd 02 17 00 da fd ff 12 c0 ff ff 00 c8 04 ec ff 15 a9 ff ff ff ff ff ff 73 00 00 07 43 ec 88 01 d6 de cc ff ff ff ff 80 ff 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff f6"
+        val msg2 = "23 23 02 31 37 36 39 31 35 33 31 39 30 39 31 32 30 30 30 36 01 01 00 42 13 09 11 08 3b 36 02 00 3b 00 00 d4 00 00 12 c0 09 5e 00 c8 00 c8 00 15 a9 00 00 00 00 00 00 73 00 00 00 b9 1b c7 00 2e e1 25 00 00 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 dc"
+        val packageData = vehicleDataDecoder.decode(msg)
+
+        val obdData = ObdData().apply {
+            obdVin = packageData.deviceCode
+        }
+        when (packageData.commandUnit) {
+            ObdCommandUnit.CarRegister.value -> {
+                packageData.dataUnit.forEach {
+                    when (it) {
+                        is CarRegisterData -> {
+                            obdData.apply {
+                                obdTime = it.time
+                            }
+                        }
+                    }
+                }
+            }
+            ObdCommandUnit.RealTimeData.value,
+            ObdCommandUnit.ReplacementData.value -> {
+
+                packageData.dataUnit.forEach {
+                    obdData.apply {
+                        obdTime = it.time
+                    }
+                    when (it) {
+                        is com.flightfeather.uav.socket.bean.ObdInfo -> {
+                            obdData.apply {
+                                obdProtocol = it.obdProtocol
+                                obdMil = it.obdMil
+                                obdIdCode = it.obdCrn
+                                obdVerificationCode = it.obdCvn
+                                obdFaultCodeNum = it.obdFaultCodeNum
+                                obdFaultCode = it.obdFaultCode
+                            }
+                        }
+                        is EngineDataStream -> {
+                            obdData.apply {
+                                obdLng = it.obdLong
+                                obdLat = it.obdLat
+                                obdSpeed = it.obdSpeed?.toInt()
+                                obdAirPressure = it.obdAirPressure
+                                obdEngineTorque = it.obdEngineTorque
+                                obdFrictionTorque = it.obdFrictionTorque
+                                obdEngineRpm = it.obdEngineRpm?.toInt()
+                                obdStartFuelFlow = it.obdEngineFuelFlow
+                                obdScrUpstreamNo = it.obdScrUpstreamNox
+                                obdScrDownstreamNo = it.obdScrDownstreamNox
+                                obdRemainReactant = it.obdRemainReactant
+                                obdAirInput = it.obdAirInput
+                                obdScrInputTemp = it.obdScrInputTemp
+                                obdScrOutputTemp = it.obdScrOutputTemp
+                                obdDpf = it.obdDpf
+                                obdEngineCoolantTemp = it.obdEngineCoolantTemp
+                                obdFuelLevel = it.obdFuelLevel
+                                obdLocationStatus = it.obdLocationStatus
+                                obdTotalMileage = it.obdTotalMileage
+                            }
+                        }
+                        is SupplementDataStream -> {
+                            obdData.apply {
+                                obdEngineTorqueMode = it.obdEngineTorqueMode?.toString()
+                                obdAcceleratorPedal = it.obdAcceleratorPedal
+                                obdTotalOilConsumption = it.obdTotalOilConsumption
+                                obdUreaBoxTemp = it.obdUreaBoxTemp
+                                obdUreaVolume = it.obdUreaVolume?.toInt()
+                                obdTotalUreaConsume = it.obdTotalUreaConsume
+                                obdDpfTemp = it.obdDpfTemp
+//                                obdFirmwareVersion =
+                            }
+                        }
+                    }
+                }
+
+            }
+            ObdCommandUnit.CarLogOut.value -> {
+
+            }
+            ObdCommandUnit.TimeCalibration.value -> {
+
+            }
+        }
+    }
+}
\ No newline at end of file

--
Gitblit v1.9.3