¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.flightfeather.uav.common.config |
| | | |
| | | import org.springframework.context.annotation.Bean |
| | | import org.springframework.context.annotation.Configuration |
| | | import org.springframework.web.cors.CorsConfiguration |
| | | import org.springframework.web.cors.UrlBasedCorsConfigurationSource |
| | | import org.springframework.web.filter.CorsFilter |
| | | |
| | | @Configuration |
| | | class CorsConfig { |
| | | |
| | | private fun buildConfig(): CorsConfiguration { |
| | | return CorsConfiguration().apply { |
| | | addAllowedOrigin("*") |
| | | addAllowedHeader("*") |
| | | addAllowedMethod("*") |
| | | allowCredentials = true |
| | | } |
| | | } |
| | | |
| | | @Bean |
| | | fun corsFilter(): CorsFilter { |
| | | val source = UrlBasedCorsConfigurationSource().apply { |
| | | registerCorsConfiguration("/**", buildConfig()) |
| | | } |
| | | |
| | | return CorsFilter(source) |
| | | } |
| | | } |
| | |
| | | class FileUtil { |
| | | |
| | | private var file: File |
| | | private var basePath:String = "${File.separator}ObdData${File.separator}" |
| | | private var basePath:String = "${File.separator}UAVData${File.separator}" |
| | | private var closeThread: Thread? = null |
| | | private var fw: FileWriter? = null |
| | | private var bw: BufferedWriter? = null |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.flightfeather.uav.common.utils |
| | | |
| | | import com.google.gson.Gson |
| | | import com.google.gson.JsonParser |
| | | import java.util.ArrayList |
| | | |
| | | /** |
| | | * @author riku |
| | | * Date: 2019/4/28 |
| | | * GSONåºååå·¥å
·ç±» |
| | | */ |
| | | object GsonUtils { |
| | | |
| | | fun getNoteJsonString(jsonString: String, note: String): String { |
| | | if (jsonString.isEmpty()) { |
| | | throw RuntimeException("getNoteJsonString jsonString empty") |
| | | } |
| | | if (note.isEmpty()) { |
| | | throw RuntimeException("getNoteJsonString note empty") |
| | | } |
| | | val element = JsonParser().parse(jsonString) |
| | | if (element.isJsonNull) { |
| | | throw RuntimeException("getNoteJsonString element empty") |
| | | } |
| | | return element.asJsonObject.get(note).toString() |
| | | } |
| | | |
| | | |
| | | fun <T> parserJsonToArrayBeans(jsonString: String, note: String, beanClazz: Class<T>): List<T> { |
| | | val noteJsonString = getNoteJsonString(jsonString, note) |
| | | return parserJsonToArrayBeans(noteJsonString, beanClazz) |
| | | } |
| | | |
| | | |
| | | fun <T> parserJsonToArrayBeans(jsonString: String, beanClazz: Class<T>): List<T> { |
| | | if (jsonString.isEmpty()) { |
| | | throw RuntimeException("parserJsonToArrayBeans jsonString empty") |
| | | } |
| | | val jsonElement = JsonParser().parse(jsonString) |
| | | if (jsonElement.isJsonNull) { |
| | | throw RuntimeException("parserJsonToArrayBeans jsonElement empty") |
| | | } |
| | | if (!jsonElement.isJsonArray) { |
| | | throw RuntimeException("parserJsonToArrayBeans jsonElement is not JsonArray") |
| | | } |
| | | val jsonArray = jsonElement.asJsonArray |
| | | val beans = ArrayList<T>() |
| | | for (jsonElement2 in jsonArray) { |
| | | val bean = Gson().fromJson(jsonElement2, beanClazz) |
| | | beans.add(bean) |
| | | } |
| | | return beans |
| | | } |
| | | |
| | | |
| | | fun <T> parserJsonToBean(jsonString: String, clazzBean: Class<T>): T { |
| | | if (jsonString.isEmpty()) { |
| | | throw RuntimeException("parserJsonToBean jsonString empty") |
| | | } |
| | | val jsonElement = JsonParser().parse(jsonString) |
| | | if (jsonElement.isJsonNull) { |
| | | throw RuntimeException("parserJsonToBean jsonElement empty") |
| | | } |
| | | if (!jsonElement.isJsonObject) { |
| | | throw RuntimeException("parserJsonToBean is not object") |
| | | } |
| | | return Gson().fromJson(jsonElement, clazzBean) |
| | | } |
| | | |
| | | |
| | | fun <T> parserJsonToBean(jsonString: String, note: String, clazzBean: Class<T>): T { |
| | | val noteJsonString = getNoteJsonString(jsonString, note) |
| | | return parserJsonToBean(noteJsonString, clazzBean) |
| | | } |
| | | |
| | | |
| | | fun toJsonString(obj: Any?): String { |
| | | return if (obj != null) { |
| | | Gson().toJson(obj) |
| | | } else { |
| | | throw RuntimeException("obj could not be empty") |
| | | } |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.flightfeather.uav.lightshare.bean |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonInclude |
| | | |
| | | |
| | | /** |
| | | * @author riku |
| | | * Date: 2020/10/9 |
| | | * ç½ç»è¯·æ±è¿åæ°æ®åºç±» |
| | | */ |
| | | //"请æ±è¿ååºæ¬ç»æ" |
| | | @JsonInclude(JsonInclude.Include.NON_NULL) |
| | | data class BaseResponse<T>( |
| | | var success: Boolean, |
| | | var message: String = "", |
| | | val head: DataHead? = null, |
| | | val data: T? = null |
| | | ){ |
| | | init { |
| | | if (message.isBlank()) { |
| | | message = if (success) { |
| | | "è¯·æ±æå" |
| | | } else { |
| | | "请æ±å¤±è´¥" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | //"å页信æ¯" |
| | | data class DataHead( |
| | | var page: Int = 1, |
| | | var totalPage: Int = 1 |
| | | ) |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.flightfeather.uav.lightshare.bean |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonInclude |
| | | import com.flightfeather.uav.socket.bean.AirData |
| | | |
| | | /** |
| | | * @author riku |
| | | * Date: 2020/9/10 |
| | | */ |
| | | @JsonInclude(JsonInclude.Include.NON_NULL) |
| | | data class DataVo( |
| | | //æ¶é´, yyyy-MM-dd HH:mm:ss |
| | | var time: String? = null, |
| | | //ç«ç¹ç¼å· |
| | | var deviceCode: String? = null, |
| | | //æ°æ®å¼ |
| | | var values: List<AirData>? = null, |
| | | //ç»åº¦ |
| | | var lng: Double? = null, |
| | | //纬度 |
| | | var lat: Double? = null |
| | | ) |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.flightfeather.uav.lightshare.service |
| | | |
| | | import com.flightfeather.uav.lightshare.bean.BaseResponse |
| | | import com.flightfeather.uav.lightshare.bean.DataVo |
| | | |
| | | interface RealTimeDataService { |
| | | |
| | | fun getSecondData(deviceCode: String?, page: Int?, perPage: Int?): BaseResponse<List<DataVo>> |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.flightfeather.uav.lightshare.service.impl |
| | | |
| | | import com.flightfeather.uav.common.utils.GsonUtils |
| | | import com.flightfeather.uav.domain.entity.RealTimeData |
| | | import com.flightfeather.uav.domain.mapper.RealTimeDataMapper |
| | | import com.flightfeather.uav.lightshare.bean.BaseResponse |
| | | import com.flightfeather.uav.lightshare.bean.DataHead |
| | | import com.flightfeather.uav.lightshare.bean.DataVo |
| | | import com.flightfeather.uav.lightshare.service.RealTimeDataService |
| | | import com.flightfeather.uav.socket.bean.AirData |
| | | import com.github.pagehelper.PageHelper |
| | | import org.springframework.stereotype.Service |
| | | import tk.mybatis.mapper.entity.Example |
| | | import java.text.SimpleDateFormat |
| | | |
| | | @Service |
| | | class RealTimeDataServiceImpl(val realTimeDataMapper: RealTimeDataMapper) : RealTimeDataService { |
| | | |
| | | override fun getSecondData(deviceCode: String?, page: Int?, perPage: Int?): BaseResponse<List<DataVo>> { |
| | | val _perPage = perPage ?: 60 |
| | | val _page = page ?: 1 |
| | | val pageInfo = PageHelper.startPage<RealTimeData>(_page, _perPage) |
| | | val result = mutableListOf<DataVo>() |
| | | realTimeDataMapper.selectByExample(Example(RealTimeData::class.java).apply { |
| | | createCriteria().apply { |
| | | deviceCode?.let { andEqualTo("deviceCode", it) } |
| | | } |
| | | orderBy("dataTime").desc() |
| | | }).forEach { |
| | | result.add(DataVo( |
| | | SimpleDateFormat.getDateTimeInstance().format(it.dataTime), |
| | | it.deviceCode, |
| | | GsonUtils.parserJsonToArrayBeans(it.factors, AirData::class.java), |
| | | it.longitude.toDouble(), it.latitude.toDouble() |
| | | )) |
| | | } |
| | | result.reverse() |
| | | return BaseResponse(true, head = DataHead(pageInfo.pageNum, pageInfo.pages), data = result) |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.flightfeather.uav.lightshare.web |
| | | |
| | | import com.flightfeather.uav.lightshare.service.RealTimeDataService |
| | | 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 |
| | | |
| | | @RestController |
| | | @RequestMapping("air/realtime") |
| | | class RealTimeDataController(val realTimeDataService: RealTimeDataService) { |
| | | |
| | | @GetMapping("/sec") |
| | | fun getSecondData( |
| | | @RequestParam(value = "deviceCode", required = false) deviceCode: String?, |
| | | @RequestParam(value = "page", required = false) page: Int?, |
| | | @RequestParam(value = "perPage", required = false) perPage: Int? |
| | | ) = realTimeDataService.getSecondData(deviceCode,page, perPage) |
| | | } |
| | |
| | | |
| | | companion object{ |
| | | private lateinit var instance: MessageManager |
| | | |
| | | private const val TAG = "UAV" |
| | | } |
| | | |
| | | @Autowired |
| | |
| | | if (bccCheck(msg)) { |
| | | //ä¿å |
| | | DeviceSession.saveDevice(packageData.deviceCode, ctx) |
| | | // saveToTxt(msg) |
| | | saveToTxt(msg) |
| | | saveToDataBase(packageData) |
| | | } else { |
| | | println("------æ°æ®BCCæ ¡éªå¤±è´¥ï¼èå¼ [${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}]") |
| | | println("------${TAG}æ°æ®BCCæ ¡éªå¤±è´¥ï¼èå¼ [${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}]") |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | class ServerHandler : ChannelInboundHandlerAdapter() { |
| | | |
| | | companion object { |
| | | private const val TAG = "UAV" |
| | | } |
| | | |
| | | val attributeKey = AttributeKey.valueOf<String>("deviceCode") |
| | | val messageManager = MessageManager() |
| | | |
| | | override fun channelRegistered(ctx: ChannelHandlerContext?) { |
| | | super.channelRegistered(ctx) |
| | | println("------ç«¯å£æIPè¿æ¥ï¼[ip:${ctx?.channel()?.remoteAddress()}] ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}") |
| | | println() |
| | | println("------${TAG}ç«¯å£æIPè¿æ¥ï¼[ip:${ctx?.channel()?.remoteAddress()}] ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}") |
| | | // ctx?.fireChannelActive() |
| | | } |
| | | |
| | | override fun channelActive(ctx: ChannelHandlerContext?) { |
| | | println("------ç«¯å£æIPæ¿æ´»ï¼[ip:${ctx?.channel()?.remoteAddress()}] ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}") |
| | | println() |
| | | println("------${TAG}ç«¯å£æIPæ¿æ´»ï¼[ip:${ctx?.channel()?.remoteAddress()}] ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}") |
| | | super.channelActive(ctx) |
| | | } |
| | | |
| | |
| | | val sb = StringBuilder() |
| | | |
| | | if (msg is ByteArray) { |
| | | println("------æ¶å°çåå§æ°æ®ï¼[ip:${ctx?.channel()?.remoteAddress()}] ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}") |
| | | println() |
| | | println("------${TAG}æ¶å°çåå§æ°æ®ï¼[ip:${ctx?.channel()?.remoteAddress()}] ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}") |
| | | msg.forEach { |
| | | val a: Int = if (it < 0) { |
| | | it + 256 |
| | |
| | | } |
| | | val str = sb.toString() |
| | | if (str.isNotEmpty()) { |
| | | MessageManager().dealStringMsg(str, ctx) |
| | | messageManager.dealStringMsg(str, ctx) |
| | | } |
| | | |
| | | } |
| | |
| | | } |
| | | |
| | | override fun channelInactive(ctx: ChannelHandlerContext?) { |
| | | println("------ç«¯å£æIP䏿´»å¨ï¼[ip:${ctx?.channel()?.remoteAddress()}] ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}") |
| | | println("------${TAG}ç«¯å£æIP䏿´»å¨ï¼[ip:${ctx?.channel()?.remoteAddress()}] ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}") |
| | | super.channelInactive(ctx) |
| | | } |
| | | |
| | |
| | | package com.flightfeather.uav.socket |
| | | |
| | | import com.flightfeather.uav.socket.decoder.impl.DataPackageDecoderImpl |
| | | import io.netty.buffer.ByteBuf |
| | | import io.netty.channel.ChannelHandlerContext |
| | | import io.netty.handler.codec.ByteToMessageDecoder |
| | |
| | | class UAVByteDataDecoder : ByteToMessageDecoder() { |
| | | |
| | | companion object { |
| | | private const val HEAD_BYTES = 2//æ°æ®å¤´æå é¿åº¦ |
| | | private const val LENGTH_BYTES = 1//æ°æ®ä½æ°æå é¿åº¦ |
| | | private const val BCC_BYTES = 2//æ ¡éªç é¿åº¦ |
| | | const val BASE_LENGTH = HEAD_BYTES + LENGTH_BYTES + BCC_BYTES |
| | | const val BASE_LENGTH = DataPackageDecoderImpl.HEAD_BYTES + DataPackageDecoderImpl.COMMAND_UNIT_BYTES + |
| | | DataPackageDecoderImpl.DEVICE_CODE_BYTES + DataPackageDecoderImpl.DATA_LENGTH + DataPackageDecoderImpl.BCC_BYTES |
| | | const val HEAD1 = 0x01.toByte() |
| | | const val HEAD_LENGTH = DataPackageDecoderImpl.HEAD_BYTES + DataPackageDecoderImpl.COMMAND_UNIT_BYTES + |
| | | DataPackageDecoderImpl.DEVICE_CODE_BYTES |
| | | } |
| | | |
| | | override fun decode(p0: ChannelHandlerContext?, p1: ByteBuf?, p2: MutableList<Any>?) { |
| | |
| | | // æ è®°å
头å¼å§çindex |
| | | it.markReaderIndex() |
| | | // 读å°äºåè®®çå¼å§æ å¿ï¼ç»æwhileå¾ªç¯ |
| | | val b = ByteArray(2) |
| | | val b = ByteArray(HEAD_LENGTH) |
| | | it.readBytes(b) |
| | | if (b[0] == HEAD1) { |
| | | dataList.add(b[0]) |
| | | dataList.add(b[1]) |
| | | b.forEach {b -> |
| | | dataList.add(b) |
| | | } |
| | | break |
| | | } |
| | | |
| | |
| | | //æ°æ®åå
çé¿åº¦ |
| | | val length = getDataUnitLength(it, dataList) |
| | | // å¤æè¯·æ±æ°æ®åå
æ°æ®å[LENGTH_BYTES]个åèçæ ¡éªç æ¯å¦å°é½ |
| | | if (it.readableBytes() < length + BCC_BYTES) { |
| | | if (it.readableBytes() < length + DataPackageDecoderImpl.BCC_BYTES) { |
| | | // è¿å读æé |
| | | it.readerIndex(beginReader) |
| | | return |
| | | } |
| | | |
| | | //è¯»åæ°æ®åå
åæ ¡éªç æ°æ® |
| | | ByteArray(length + BCC_BYTES).apply { |
| | | ByteArray(length + DataPackageDecoderImpl.BCC_BYTES).apply { |
| | | it.readBytes(this) |
| | | }.forEach {b -> |
| | | dataList.add(b) |
| | |
| | | //æ°æ®ä¸çä¿çåèæ° |
| | | const val RESERVED_DATA_COUNT = 12 |
| | | |
| | | //ä¸ä¸ªå¨æçæµå åç屿§æå åèæ° |
| | | const val FACTOR_BIT_LENGTH_1 = 6 |
| | | |
| | | //ä¸ä¸ªä¿ççæµå åç屿§æå åèæ° |
| | | const val FACTOR_BIT_LENGTH_2 = 3 |
| | | |
| | | //ä¸ä¸ªå¨æçæµå åç屿§æå åèæ° |
| | | const val FACTOR_BIT_LENGTH_1 = 6 |
| | | const val FACTOR_BIT_LENGTH_3 = 2 |
| | | } |
| | | } |
| | |
| | | * æ ¹æ®å½ä»¤åå
@see [AirCommandUnit] çåç±»ï¼ä¸åç±»åçç»æä¸åï¼è§ååç±» |
| | | */ |
| | | open class DataUnit { |
| | | var time: Date? = null |
| | | |
| | | } |
| | |
| | | */ |
| | | interface DataUnitDecoder { |
| | | |
| | | fun getAirConfirmData(b: List<String>): List<AirTypeData> |
| | | fun getAirConfirmData(b: List<String>, deviceCode: String?): List<AirTypeData> |
| | | |
| | | fun getAirData(b: List<String>): List<AirData> |
| | | fun getAirData(b: List<String>, deviceCode: String?): List<AirData> |
| | | |
| | | } |
| | |
| | | import com.flightfeather.uav.socket.decoder.DataUnitDecoder |
| | | import com.flightfeather.uav.socket.eunm.AirCommandUnit |
| | | import java.util.* |
| | | import kotlin.text.StringBuilder |
| | | |
| | | /** |
| | | * @author riku |
| | |
| | | */ |
| | | class DataPackageDecoderImpl : DataPackageDecoder { |
| | | |
| | | companion object { |
| | | const val HEAD_BYTES = 1 |
| | | const val COMMAND_UNIT_BYTES = 1 |
| | | const val DEVICE_CODE_BYTES = 1 |
| | | const val DATA_LENGTH = 1 |
| | | const val BCC_BYTES = 2 |
| | | } |
| | | |
| | | private val dataUnitDecoder: DataUnitDecoder = DataUnitDecoderImpl() |
| | | |
| | | |
| | | override fun getHead(b: List<String>): String? { |
| | | return if (b.isNotEmpty()) { |
| | | b[0] |
| | | val s = StringBuilder() |
| | | repeat(HEAD_BYTES) { |
| | | s.append(b[it]) |
| | | } |
| | | s.toString() |
| | | } else { |
| | | null |
| | | } |
| | | } |
| | | |
| | | override fun getCommandUnit(b: List<String>): Int? = if (b.size >= 2) { |
| | | b[1].toIntOrNull(16) |
| | | override fun getCommandUnit(b: List<String>): Int? = if (b.size >= (HEAD_BYTES + COMMAND_UNIT_BYTES)) { |
| | | val s = StringBuilder() |
| | | repeat(COMMAND_UNIT_BYTES) { |
| | | s.append(b[HEAD_BYTES + it]) |
| | | } |
| | | s.toString().toIntOrNull(16) |
| | | } else { |
| | | null |
| | | } |
| | | |
| | | override fun getDeviceCode(b: List<String>): String? { |
| | | return null |
| | | override fun getDeviceCode(b: List<String>): String? = if (b.size >= (HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES)) { |
| | | //2021/1/7 '0A'代表车载设å¤ï¼'0B'代表æ 人æºè®¾å¤ |
| | | val s = StringBuilder() |
| | | repeat(DEVICE_CODE_BYTES) { |
| | | s.append(b[HEAD_BYTES + COMMAND_UNIT_BYTES + it]) |
| | | } |
| | | s.toString() |
| | | } else { |
| | | null |
| | | } |
| | | |
| | | override fun getDataTime(b: List<String>): Date { |
| | | //fixme 2020/06/11 ç®åæ°æ®æµä¸ä¸å
å«éæ ·æ¶é´ï¼æä»¥éç¨æå¡å¨æ¥æ¶æ¶é´ä½ä¸ºéæ ·æ¶é´ |
| | | // FIXME: 2021/1/7 éæ ·æ¶é´åçæµå åä¸åæ¾å¨äºæ°æ®é¨åï¼æ¤å¤ä¸ååè§£æ |
| | | return Date() |
| | | } |
| | | |
| | | override fun getDataLength(b: List<String>): Int { |
| | | if (b.size < 5) return 0 |
| | | if (b.size <= HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES + DATA_LENGTH) return 0 |
| | | |
| | | val hexNum = b[2] |
| | | val hexNum = b[HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES] |
| | | |
| | | return hexNum.toIntOrNull(16) ?: 0 |
| | | } |
| | | |
| | | override fun getDataUnit(b: List<String>): List<DataUnit> { |
| | | if (getDataLength(b) == 0 || b.size < 5) { |
| | | if (getDataLength(b) == 0 || b.size <= HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES + DATA_LENGTH) { |
| | | return emptyList() |
| | | } |
| | | |
| | | val unit = mutableListOf<String>() |
| | | for (i in 3..b.size - 3) { |
| | | val start = HEAD_BYTES + COMMAND_UNIT_BYTES + DEVICE_CODE_BYTES + DATA_LENGTH |
| | | for (i in start..b.size - 1 - BCC_BYTES) { |
| | | unit.add(b[i]) |
| | | } |
| | | |
| | | dataUnitDecoder.run { |
| | | return when (getCommandUnit(b)) { |
| | | AirCommandUnit.Confirm.value -> getAirConfirmData(unit) |
| | | AirCommandUnit.AirData.value -> getAirData(unit) |
| | | AirCommandUnit.Confirm.value -> getAirConfirmData(unit, getDeviceCode(b)) |
| | | AirCommandUnit.AirData.value -> getAirData(unit, getDeviceCode(b)) |
| | | else -> emptyList() |
| | | } |
| | | } |
| | |
| | | |
| | | private val logger = LoggerFactory.getLogger(javaClass.name) |
| | | |
| | | private val types = mutableListOf<AirTypeData>() |
| | | private val types = mutableMapOf<String?, MutableList<AirTypeData>>() |
| | | |
| | | override fun getAirConfirmData(b: List<String>): List<AirTypeData> { |
| | | override fun getAirConfirmData(b: List<String>, deviceCode: String?): List<AirTypeData> { |
| | | val resultList = mutableListOf<AirTypeData>() |
| | | b.forEach { |
| | | FactorType.getByIndex(it.toInt(16))?.let { f-> |
| | | resultList.add(AirTypeData(f)) |
| | | } |
| | | } |
| | | types.clear() |
| | | types.addAll(resultList) |
| | | if (!types.containsKey(deviceCode)) { |
| | | types[deviceCode] = mutableListOf() |
| | | } |
| | | types[deviceCode]?.clear() |
| | | types[deviceCode]?.addAll(resultList) |
| | | |
| | | return resultList |
| | | } |
| | | |
| | | override fun getAirData(b: List<String>): List<AirData> { |
| | | override fun getAirData(b: List<String>, deviceCode: String?): List<AirData> { |
| | | val resultList = mutableListOf<AirData>() |
| | | |
| | | if (!types.containsKey(deviceCode)) { |
| | | return resultList |
| | | } |
| | | |
| | | var i = 0 |
| | | types.forEach { |
| | | types[deviceCode]?.forEach { |
| | | if (i > b.size - it.factorType.byteLength) { |
| | | return@forEach |
| | | } |
| | |
| | | when (it.factorType) { |
| | | FactorType.LNG -> { |
| | | val valid = b[i].toInt(16).toChar()//ç»çº¬åº¦æ¯å¦ææï¼ææ: A; æ æ: Vï¼ |
| | | val a1 = b[i + 1].toInt(16) |
| | | val b1 = b[i + 2].toInt(16) |
| | | var b2 = "${b[i + 3]}${b[i + 4]}".toInt(16).toDouble() |
| | | while (b2 >= 1) { |
| | | b2 /= 10 |
| | | } |
| | | val lng = a1 + (b1 + b2) / 60 |
| | | |
| | | //ç»çº¬åº¦åå§å¼ï¼ä¾ï¼121°30.0411â²ï¼å
¶ä¸ 121 对åºa1ï¼30对åºb1ï¼04对åºb2ï¼11对åºb3 |
| | | val a1 = b[i + 1].toInt(16)//度 |
| | | val b1 = b[i + 2].toInt(16)//åï¼æ´æ°ï¼ |
| | | var b2 = b[i + 3].toInt(16).toDouble()//åï¼å°æ°é¨åå两ä½ï¼ |
| | | var b3 = b[i + 4].toInt(16).toDouble()//åï¼å°æ°é¨åå两ä½ï¼ |
| | | |
| | | // var b2 = "${b[i + 3]}${b[i + 4]}".toInt(16).toDouble() |
| | | b2 /= 100 |
| | | b3 /= 10000 |
| | | val lng = a1 + (b1 + b2 + b3) / 60 |
| | | val s = b[i + 5].toInt(16).toChar() |
| | | |
| | | resultList.add(AirData().apply { |
| | |
| | | FactorType.LAT -> { |
| | | val a1 = b[i].toInt(16) |
| | | val b1 = b[i + 1].toInt(16) |
| | | var b2 = "${b[i + 2]}${b[i + 3]}".toInt(16).toDouble() |
| | | while (b2 >= 1) { |
| | | b2 /= 10 |
| | | } |
| | | val lat = a1 + (b1 + b2) / 60 |
| | | var b2 = b[i + 2].toInt(16).toDouble()//åï¼å°æ°é¨åå两ä½ï¼ |
| | | var b3 = b[i + 3].toInt(16).toDouble()//åï¼å°æ°é¨åå两ä½ï¼ |
| | | |
| | | b2 /= 100 |
| | | b3 /= 10000 |
| | | val lat = a1 + (b1 + b2 + b3) / 60 |
| | | val s = b[i + 4].toInt(16).toChar() |
| | | resultList.add(AirData().apply { |
| | | factorId = it.factorType.value.toString() |
| | |
| | | physicalQuantity = data2 |
| | | }) |
| | | } |
| | | AirDataPackage.FACTOR_BIT_LENGTH_3 -> { |
| | | val data = "${b[i]}${b[i + 1]}".toInt(16) |
| | | resultList.add(AirData().apply { |
| | | factorId = it.factorType.value.toString() |
| | | factorName = it.factorType.des |
| | | factorData = data.toDouble() |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | LNG(12,"LNG",6),//ç»åº¦ |
| | | LAT(13,"LAT",5),//纬度 |
| | | VELOCITY(14, "VELOCITY", 3),//é度 |
| | | TIME(15, "TIME", 6);//æ¶é´ |
| | | TIME(15, "TIME", 6),//æ¶é´ |
| | | WIND_SPEED(16, "WIND_SPEED", 3), |
| | | WIND_DIRECTION(17, "WIND_DIRECTION", 2); |
| | | |
| | | companion object { |
| | | |
| | |
| | | LAT.value -> LAT |
| | | VELOCITY.value -> VELOCITY |
| | | TIME.value -> TIME |
| | | WIND_SPEED.value -> WIND_SPEED |
| | | WIND_DIRECTION.value -> WIND_DIRECTION |
| | | else -> null |
| | | } |
| | | } |
| | |
| | | url: jdbc:mysql://114.215.109.124:3306/dronemonitor?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false |
| | | username: root |
| | | password: 123456 |
| | | hikari: |
| | | maximum-pool-size: 500 |
| | | minimum-idle: 20 |
| | | idle-timeout: 60000 |
| | | connection-timeout: 60000 |
| | | jmx: |
| | | enabled: false |
| | | |
| | |
| | | package com.flightfeather.uav |
| | | |
| | | import com.flightfeather.uav.socket.bean.DataUnit |
| | | import com.flightfeather.uav.socket.decoder.AirDataDecoder |
| | | import com.flightfeather.uav.socket.eunm.AirCommandUnit |
| | | import com.google.gson.Gson |
| | | import org.junit.Test |
| | | import java.io.File |
| | | import java.io.FileOutputStream |
| | | import java.io.OutputStreamWriter |
| | | import java.text.SimpleDateFormat |
| | | import java.util.* |
| | | |
| | | /** |
| | | * @author riku |
| | | * Date: 2019/9/12 |
| | | */ |
| | | class Test { |
| | | |
| | | @Test |
| | | fun foo1() { |
| | | val s = SimpleDateFormat.getDateTimeInstance().format(Date()) |
| | | println(s) |
| | | } |
| | | |
| | | @Test |
| | | fun foo2() { |
| | | val file = File("E:\\VSprojects\\uav-monitor\\asset\\data\\data-2020-12-24-01-34-24.txt") |
| | | val outFile = File("E:\\VSprojects\\uav-monitor\\asset\\data\\data.json") |
| | | val out = OutputStreamWriter(FileOutputStream(outFile)) |
| | | val list = mutableListOf<List<DataUnit>>() |
| | | file.readLines().forEach { |
| | | val p = AirDataDecoder.instance.decode(it) |
| | | // val str = Gson().toJson(p.dataUnit) |
| | | if (p.commandUnit == AirCommandUnit.AirData.value) { |
| | | list.add(p.dataUnit) |
| | | } |
| | | } |
| | | val str = Gson().toJson(list) |
| | | out.append(str) |
| | | out.flush() |
| | | out.close() |
| | | } |
| | | } |