desc:解析传感器数据

main
xiaowusky 2 years ago
parent 5cfa300050
commit 926bb54a18

@ -19,9 +19,32 @@ android {
} }
} }
signingConfigs {
debug {
storeFile file(rootProject.ext.sign.keystore_path)
storePassword rootProject.ext.sign.keystore_pwd
keyAlias rootProject.ext.sign.keystore_alias
keyPassword rootProject.ext.sign.keystore_pwd
}
release {
storeFile file(rootProject.ext.sign.keystore_path)
storePassword rootProject.ext.sign.keystore_pwd
keyAlias rootProject.ext.sign.keystore_alias
keyPassword rootProject.ext.sign.keystore_pwd
}
}
viewBinding { viewBinding {
enabled = true enabled = true
} }
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
signingConfig signingConfigs.release
}
}
} }
@ -69,4 +92,6 @@ dependencies {
annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.0.0' annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.0.0'
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0' implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
implementation 'com.aill:AndroidSerialPort:1.0.8'
} }

@ -34,18 +34,6 @@ object TestUtils {
TxtOverlay.setShowTip("co2:50%@co:44%") TxtOverlay.setShowTip("co2:50%@co:44%")
PushHelper.setPushUrl("rtsp://192.168.5.17:554/123") PushHelper.setPushUrl("rtsp://192.168.5.17:554/123")
GlobalScope.launch() { GlobalScope.launch() {
// 插入类型
val typeDao = DBUtils.gasTypeDao()
val all = typeDao.getAll()
if (all.isNotEmpty()) {
return@launch
}
val list = mutableListOf<GasType>()
list.add(GasType("CO", "", false))
list.add(GasType("CO2", "", false))
list.add(GasType("O2", "", false))
typeDao.insertAll(list)
// 构造气体数据 // 构造气体数据
val timeMillis = System.currentTimeMillis() val timeMillis = System.currentTimeMillis()

@ -4,12 +4,12 @@ import com.common.commonlib.CommonApplication
import com.common.commonlib.db.DBUtils import com.common.commonlib.db.DBUtils
import com.common.commonlib.db.dao.WarningDao import com.common.commonlib.db.dao.WarningDao
import com.common.commonlib.db.entity.Warning import com.common.commonlib.db.entity.Warning
import com.lztek.toolkit.Lztek
import com.yinuo.safetywatcher.TestUtils import com.yinuo.safetywatcher.TestUtils
import com.yinuo.safetywatcher.watcher.constant.CAMERA_DNS import com.yinuo.safetywatcher.watcher.constant.CAMERA_DNS
import com.yinuo.safetywatcher.watcher.constant.CAMERA_GATEWAY import com.yinuo.safetywatcher.watcher.constant.CAMERA_GATEWAY
import com.yinuo.safetywatcher.watcher.constant.CAMERA_IP import com.yinuo.safetywatcher.watcher.constant.CAMERA_IP
import com.yinuo.safetywatcher.watcher.constant.CAMERA_NETMASK import com.yinuo.safetywatcher.watcher.constant.CAMERA_NETMASK
import com.yinuo.safetywatcher.watcher.port.cmd.GasPortStatus
import com.yinuo.safetywatcher.watcher.utils.LztekUtil import com.yinuo.safetywatcher.watcher.utils.LztekUtil
import com.yinuo.safetywatcher.watcher.wifi.WiFiConfig import com.yinuo.safetywatcher.watcher.wifi.WiFiConfig
import com.yinuo.safetywatcher.watcher.wifi.WiFiModule import com.yinuo.safetywatcher.watcher.wifi.WiFiModule
@ -23,7 +23,7 @@ import java.io.File
class App : CommonApplication() { class App : CommonApplication() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
LztekUtil.setObject(Lztek.create(this)) // LztekUtil.setObject(Lztek.create(this))
ipConfig() ipConfig()
wifiConfig() wifiConfig()
tryFixDbData() tryFixDbData()
@ -73,7 +73,7 @@ class App : CommonApplication() {
val gasTypeDao = DBUtils.gasTypeDao() val gasTypeDao = DBUtils.gasTypeDao()
val all = gasTypeDao.getAll() val all = gasTypeDao.getAll()
all.onEach { gasType -> all.onEach { gasType ->
gasType.online = false gasType.status = GasPortStatus.OUTLINE
gasTypeDao.insert(gasType) gasTypeDao.insert(gasType)
} }
}.await() }.await()

@ -1,24 +1,20 @@
package com.yinuo.safetywatcher.watcher.port package com.yinuo.safetywatcher.watcher.port
import android.os.Handler import com.common.serialport.ComMultiPortUtils
import android.os.Looper import com.yinuo.safetywatcher.watcher.port.cmd.CMD
import com.common.commonlib.db.DBUtils
import com.common.commonlib.db.entity.GasType
import com.yinuo.library.vlc.TxtOverlay
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Runnable
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
object GasUtils { object GasUtils {
private const val BAUD_RATE = 9600 private const val BAUD_RATE = 9600
private const val FULL_MSG_SIZE = 9 private const val PORT_PATH = "/dev/ttyS1"
private const val CHECK_TIME = 10000L const val FULL_MSG_SIZE = 9
private val mPortFlags = booleanArrayOf(false, false, false, false) const val CHECK_TIME = 10000L
private val mPortRunnable = hashMapOf<Int, FlagRunnable>() private const val READ_MSG_INTERVAL = 500L
private val mHandler = Handler(Looper.getMainLooper()) private var mInitFlag = false
fun initPort() { fun initPort() {
openPorts() openPorts()
@ -26,56 +22,32 @@ object GasUtils {
} }
private fun openPorts() { private fun openPorts() {
if (!mPortFlags[0]) { if (!mInitFlag) {
PlatformMultiPortUtils.openPort("/dev/tyyS0", BAUD_RATE) { ComMultiPortUtils.openPort(PORT_PATH, BAUD_RATE) {
if (it.isNotEmpty() && it.size >= FULL_MSG_SIZE) { mInitFlag = true
val checkSum = getCheckSum(it) ParseHelper.parse(it)
// 校验通过
if (checkSum == it[8]) {
val gasName = it[1]
val gasUnit = it[2]
val gasValue: Double = (it[4] * 256 + it[5]) / 100.00
setFlag(0, gasName, "/dev/tyyS0")
// TODO
TxtOverlay.setShowTip("")
}
}
}
}
if (!mPortFlags[1]) {
PlatformMultiPortUtils.openPort("/dev/tyyS1", BAUD_RATE) {}
} }
if (!mPortFlags[2]) { readGasMsg()
PlatformMultiPortUtils.openPort("/dev/tyyS2", BAUD_RATE) {}
}
if (!mPortFlags[3]) {
PlatformMultiPortUtils.openPort("/dev/tyyS3", BAUD_RATE) {}
} }
} }
@OptIn(DelicateCoroutinesApi::class) /**
private fun updateGasTypeDb(gasName: Byte, port: String, online: Boolean) { * 读取气体浓度
GlobalScope.launch { */
val typeDao = DBUtils.gasTypeDao() private fun readGasMsg() {
val gasType = typeDao.getByName(gasName.toString()) GlobalScope.launch(Dispatchers.IO) {
gasType?.online = online while (true) {
typeDao.insert(gasType ?: GasType(gasName.toString(), port, online)) // 延时一段时间后,发送指令读取气体数据
} delay(READ_MSG_INTERVAL)
ComMultiPortUtils.sendMsg(PORT_PATH, CMD.O2)
delay(READ_MSG_INTERVAL)
ComMultiPortUtils.sendMsg(PORT_PATH, CMD.CH4)
delay(READ_MSG_INTERVAL)
ComMultiPortUtils.sendMsg(PORT_PATH, CMD.CO)
delay(READ_MSG_INTERVAL)
ComMultiPortUtils.sendMsg(PORT_PATH, CMD.H2S)
} }
private fun setFlag(index: Int, gasName: Byte, port: String) {
var flagRunnable = mPortRunnable[index]
if (flagRunnable == null) {
flagRunnable = FlagRunnable(index, gasName, port)
mPortRunnable[index] = flagRunnable
} }
mHandler.removeCallbacks(flagRunnable)
// 如果一段时间内没有收到消息,认为连接断开
mHandler.postDelayed(flagRunnable, CHECK_TIME)
mPortFlags[index] = true
updateGasTypeDb(gasName, port, true)
} }
// 监控串口状态 // 监控串口状态
@ -91,27 +63,4 @@ object GasUtils {
} }
} }
} }
// 计算校验值
private fun getCheckSum(bytes: ByteArray?): Byte {
var sum: Int = 0
bytes?.forEachIndexed { index, byte ->
if (index != 0 && index < FULL_MSG_SIZE - 1) {
sum += (byte.toInt() and 0xff)
}
}
return (sum.inv() + 1).toByte()
}
class FlagRunnable(
private val index: Int,
private val gasName: Byte,
private val port: String
) : Runnable {
override fun run() {
PlatformMultiPortUtils.release(port)
mPortFlags[index] = false
updateGasTypeDb(gasName, "", false)
}
}
} }

@ -0,0 +1,144 @@
package com.yinuo.safetywatcher.watcher.port
import android.os.Handler
import android.os.Looper
import com.common.commonlib.db.DBUtils
import com.common.commonlib.db.entity.GasType
import com.common.serialport.utils.HexUtils
import com.yinuo.library.vlc.utils.LogUtils
import com.yinuo.safetywatcher.watcher.port.cmd.GasPortStatus
import com.yinuo.safetywatcher.watcher.port.cmd.ResponseHelper
import com.yinuo.safetywatcher.watcher.port.cmd.getGasTypeByCode
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlin.math.pow
object ParseHelper {
private val mPortRunnable = hashMapOf<Int, FlagRunnable>()
private val mHandler = Handler(Looper.getMainLooper())
fun parse(it: ByteArray) {
if (it.isNotEmpty() && it.size >= GasUtils.FULL_MSG_SIZE) {
// val checkSum = getCheckSum(it)
// // 校验通过
// if (checkSum == it[8]) {
// val gasName = it[1]
// val gasUnit = it[2]
// val gasValue: Double = (it[4] * 256 + it[5]) / 100.00
// setFlag(0, gasName, "/dev/tyyS0")
//
// // TODO
// TxtOverlay.setShowTip("")
// }
LogUtils.v("receive msg, ${HexUtils.byteArrToHex(it)}")
val gasIndex = it[0].toInt()
val status = it[14].toInt()
val gasType = getGasTypeByCode(it[19].toInt())
when (status) {
// 预热
0 -> {
updateGasTypeDb(gasType, GasPortStatus.PRE_HOT)
setFlag(gasIndex, gasType)
}
// 正常
1 -> {
updateGasTypeDb(gasType, GasPortStatus.OK)
setFlag(gasIndex, gasType)
parseGasData(gasType, it)
}
// 故障
2, 3, 7 -> {
updateGasTypeDb(gasType, GasPortStatus.ERROR)
setFlag(gasIndex, gasType)
}
else -> {
LogUtils.v("unKnow status, do nothing")
}
}
}
}
private fun parseGasData(gasType: String, it: ByteArray) {
val unitHex: String = HexUtils.byteArrToHex(it, 3, 3 + 2)
val unitToLong: Long = HexUtils.hexToLong(unitHex)
// 10000000000000
var unitBinaryString = java.lang.Long.toBinaryString(unitToLong)
LogUtils.v("receive msg $gasType, unitBinaryString 1 = $unitBinaryString")
if (unitBinaryString.length < 16) {
val offset = 16 - unitBinaryString.length
repeat(offset){
unitBinaryString = "0" + unitBinaryString;
}
}
LogUtils.v("receive msg, unitBinaryString 2 = $unitBinaryString")
unitBinaryString = unitBinaryString.reversed()
LogUtils.v("receive msg, unitBinaryString 3 = $unitBinaryString")
//小数点
val subSequence = unitBinaryString.subSequence(8, 12)
val pointNum = ResponseHelper.getPointNum(subSequence)
LogUtils.v("receive msg, 小数点 = $subSequence$pointNum")
// 单位
val subSequence2 = unitBinaryString.subSequence(12, 16)
val unit = ResponseHelper.getGasUnit(subSequence2)
LogUtils.v("receive msg, 单位 = $subSequence2$unit")
val c17 = unitBinaryString[6].toString()
val c18 = unitBinaryString[7].toString()
// 气体浓度
val valueHex: String = HexUtils.byteArrToHex(it, 5, 5 + 2)
val valueHexLong: Long = HexUtils.hexToLong(valueHex)
// 浓度
val value =
c18.plus(c17).plus(java.lang.Long.toBinaryString(valueHexLong)).toInt(2) / 10.0.pow(
pointNum
)
LogUtils.v("receive msg, 浓度 = $c18$c17, | $valueHex, $valueHexLong, | $value")
// 量程
val rangHex: String = HexUtils.byteArrToHex(it, 11, 11 + 2)
val rangHexLong: Long = HexUtils.hexToLong(rangHex)
LogUtils.v("receive msg, 量程 = $rangHex$rangHexLong")
}
/**
* 更新数据库
*/
@OptIn(DelicateCoroutinesApi::class)
private fun updateGasTypeDb(gasName: String, status: Int) {
GlobalScope.launch {
val typeDao = DBUtils.gasTypeDao()
val gasType = typeDao.getByName(gasName)
typeDao.insert(gasType ?: GasType(gasName, status))
}
}
/**
* 启动离线检查
*/
private fun setFlag(index: Int, gasName: String) {
var flagRunnable = mPortRunnable[index]
if (flagRunnable != null) {
mHandler.removeCallbacks(flagRunnable)
}
flagRunnable = FlagRunnable(gasName)
mPortRunnable[index] = flagRunnable
// 如果一段时间内没有收到消息,认为连接断开
mHandler.postDelayed(flagRunnable, GasUtils.CHECK_TIME)
}
/**
* 离线检查
*/
class FlagRunnable(
private val gasName: String
) : Runnable {
override fun run() {
updateGasTypeDb(gasName, GasPortStatus.OUTLINE)
}
}
}

@ -0,0 +1,10 @@
package com.yinuo.safetywatcher.watcher.port.cmd
class CMD {
companion object {
val O2 = byteArrayOf(GasAddress.ADR_O2.toByte(), 0x03, 0x00, 0x00, 0x00, 0x0A).crc16()
val CH4 = byteArrayOf(GasAddress.ADR_CH4.toByte(), 0x03, 0x00, 0x00, 0x00, 0x0A).crc16()
val CO = byteArrayOf(GasAddress.ADR_CO.toByte(), 0x03, 0x00, 0x00, 0x00, 0x0A).crc16()
val H2S = byteArrayOf(GasAddress.ADR_H2S.toByte(), 0x03, 0x00, 0x00, 0x00, 0x0A).crc16()
}
}

@ -0,0 +1,50 @@
package com.yinuo.safetywatcher.watcher.port.cmd
const val BITS_OF_BYTE = 8
const val POLYNOMIAL = 0xA001
const val INITIAL_VALUE = 0xFFFF
const val FF = 0xFF
fun ByteArray.crc16(): ByteArray {
var res = INITIAL_VALUE
for (data in this) {
res = res xor (data.toInt() and FF)
for (i in 0 until BITS_OF_BYTE) {
res = if (res and 0x0001 == 1) res shr 1 xor POLYNOMIAL else res shr 1
}
}
val lowByte: Byte = (res shr 8 and FF).toByte()
val highByte: Byte = (res and FF).toByte()
return this.plus(highByte).plus(lowByte)
}
fun IntArray.crc16(): ByteArray {
val byteArray = ByteArray(this.size + 2)
var res = INITIAL_VALUE
for (index in this.indices) {
res = res xor this[index]
byteArray[index] = this[index].toByte()
for (i in 0 until BITS_OF_BYTE) {
res = if (res and 0x0001 == 1) res shr 1 xor POLYNOMIAL else res shr 1
}
}
val lowByte: Byte = (res shr 8 and FF).toByte()
val highByte: Byte = (res and FF).toByte()
byteArray[this.size] = highByte
byteArray[this.size + 1] = lowByte
return byteArray
}
fun ByteArray.crc16Verify(): Boolean {
if (this.size < 3) throw RuntimeException("数组长度不合法")
var res = INITIAL_VALUE
for (index in 0..this.size - 3) {
res = res xor (this[index].toInt() and FF)
for (i in 0 until BITS_OF_BYTE) {
res = if (res and 0x0001 == 1) res shr 1 xor POLYNOMIAL else res shr 1
}
}
val lowByte: Byte = (res shr 8 and FF).toByte()
val highByte: Byte = (res and FF).toByte()
return highByte == this[this.size - 2] && lowByte == this[this.size - 1]
}

@ -0,0 +1,18 @@
package com.yinuo.safetywatcher.watcher.port.cmd
import androidx.annotation.IntDef
@IntDef(
GasAddress.ADR_CH4,
GasAddress.ADR_O2,
GasAddress.ADR_CO,
GasAddress.ADR_H2S
)
annotation class GasAddress {
companion object {
const val ADR_CH4 = 0X01
const val ADR_O2 = 0X02
const val ADR_CO = 0X03
const val ADR_H2S = 0X04
}
}

@ -0,0 +1,19 @@
package com.yinuo.safetywatcher.watcher.port.cmd
import androidx.annotation.IntDef
@IntDef(
GasPortStatus.PRE_HOT,
GasPortStatus.OK,
GasPortStatus.ERROR,
GasPortStatus.OUTLINE
)
annotation class GasPortStatus {
companion object {
const val PRE_HOT = 0
const val OK = 1
const val ERROR = 2
const val OUTLINE = 3
}
}

@ -0,0 +1,19 @@
package com.yinuo.safetywatcher.watcher.port.cmd
enum class GasType(val code: Int, val desc: String) {
CO(5, "CO"),
CH4(11, "CH4"),
O2(67, "O2"),
H2S(52, "H2S")
}
fun getGasTypeByCode(code: Int): String {
val codes = GasType.values();
codes.forEach {
if (code == it.code) {
return it.desc;
}
}
return ""
}

@ -0,0 +1,30 @@
package com.yinuo.safetywatcher.watcher.port.cmd
object ResponseHelper {
/**
* 小数点个数
*/
fun getPointNum(sequence: CharSequence): Int {
return when (sequence) {
"0000" -> 0
"0100" -> 1
"1000" -> 2
"1100" -> 3
else -> 0
}
}
/**
* 气体单位
*/
fun getGasUnit(sequence: CharSequence): String {
return when (sequence) {
"0000" -> "ppm"
"0010" -> "%LEL"
"0100" -> "%VOL"
"0110" -> "mg/m3"
"1000" -> "ppb"
else -> ""
}
}
}

@ -7,6 +7,7 @@ import com.common.commonlib.db.entity.GasType
import com.yinuo.safetywatcher.R import com.yinuo.safetywatcher.R
import com.yinuo.safetywatcher.databinding.LayoutItemSensorBinding import com.yinuo.safetywatcher.databinding.LayoutItemSensorBinding
import com.yinuo.safetywatcher.watcher.base.BaseRvAdapter import com.yinuo.safetywatcher.watcher.base.BaseRvAdapter
import com.yinuo.safetywatcher.watcher.port.cmd.GasPortStatus
import com.yinuo.safetywatcher.watcher.ui.SensorSettingActivity import com.yinuo.safetywatcher.watcher.ui.SensorSettingActivity
class SensorAdapter : class SensorAdapter :
@ -35,17 +36,29 @@ class SensorAdapter :
} }
binding.sensorName.text = data.nickName ?: "${data.type}传感器" binding.sensorName.text = data.nickName ?: "${data.type}传感器"
val state = data.online val state = data.status
binding.sensorStatus.text = context.getText(getShowStatus(state)) binding.sensorStatus.text = context.getText(getShowStatus(state))
binding.sensorStatus.setTextColor(context.getColor(getShowStatusColor(state))) binding.sensorStatus.setTextColor(context.getColor(getShowStatusColor(state)))
} }
private fun getShowStatusColor(state: Boolean): Int { private fun getShowStatusColor(state: Int): Int {
return if (state) R.color.color_ok else R.color.color_error return when(state){
GasPortStatus.PRE_HOT -> R.color.color_prehot
GasPortStatus.OK -> R.color.color_ok
GasPortStatus.ERROR -> R.color.color_error
GasPortStatus.OUTLINE -> R.color.color_offline
else -> R.color.color_offline
}
} }
private fun getShowStatus(state: Boolean): Int { private fun getShowStatus(state: Int): Int {
return if (state) R.string.status_ok else R.string.status_offline return when(state){
GasPortStatus.PRE_HOT -> R.string.status_prehot
GasPortStatus.OK -> R.string.status_ok
GasPortStatus.ERROR -> R.string.status_error
GasPortStatus.OUTLINE -> R.string.status_offline
else -> R.string.status_offline
}
} }
} }
} }

@ -21,6 +21,7 @@
<color name="_202A45">#202A45</color> <color name="_202A45">#202A45</color>
<color name="color_ok">#01E41C</color> <color name="color_ok">#01E41C</color>
<color name="color_prehot">#f6d365</color>
<color name="color_offline">#999999</color> <color name="color_offline">#999999</color>
<color name="color_error">#E40101</color> <color name="color_error">#E40101</color>

@ -31,6 +31,7 @@
<string name="status_ok">正常</string> <string name="status_ok">正常</string>
<string name="status_offline">离线</string> <string name="status_offline">离线</string>
<string name="status_prehot">预热</string>
<string name="status_error">故障</string> <string name="status_error">故障</string>
<string name="sensor_warn_setting_txt">传感器报警值设定</string> <string name="sensor_warn_setting_txt">传感器报警值设定</string>
<string name="save">保存</string> <string name="save">保存</string>

@ -1,6 +1,6 @@
project.ext { project.ext {
sign = [ sign = [
keystore_path : "../signature/innovationapp.jks", keystore_path : "../innovationapp.jks",
keystore_pwd : "123456", keystore_pwd : "123456",
keystore_alias: "yinuo" keystore_alias: "yinuo"
] ]

Binary file not shown.

@ -7,7 +7,6 @@ import androidx.room.PrimaryKey
@Entity(tableName = "gas_type") @Entity(tableName = "gas_type")
data class GasType( data class GasType(
@PrimaryKey @ColumnInfo(name = "gas_name") var type: String, @PrimaryKey @ColumnInfo(name = "gas_name") var type: String,
@ColumnInfo(name = "port_path") var port: String, @ColumnInfo(name = "status") var status: Int = 3,
@ColumnInfo(name = "online_flag") var online: Boolean,
@ColumnInfo(name = "nick_name") var nickName: String? = null, @ColumnInfo(name = "nick_name") var nickName: String? = null,
) )

@ -42,13 +42,14 @@ class EasySerialPort<T>(
while (mStartReceiveMsg) { while (mStartReceiveMsg) {
try { try {
val ips = helper?.inputStream() val ips = helper?.inputStream()
val readByte = ips?.available()?.let { ByteArray(it) } val readByte = ByteArray(25)
readByte?.let { val size = ips?.read(readByte)
val size = ips.read(it) if (size != null) {
if (size > 0) { if (size > 0) {
mReceiver.invoke(readByte) mReceiver.invoke(readByte)
} }
} }
Thread.sleep(50L)
} catch (e: IOException) { } catch (e: IOException) {
Log.e( Log.e(
"EasySerialPort", "EasySerialPort",
@ -67,10 +68,28 @@ class EasySerialPort<T>(
* 写消息 * 写消息
*/ */
open fun write(data: ByteArray) { open fun write(data: ByteArray) {
val task = SendMsgTask(data) { // val task = SendMsgTask(data) {
// try {
// val outputStream = helper?.outputStream()
// outputStream?.write(it)
// outputStream?.flush()
// } catch (e: IOException) {
// Log.e(
// "EasySerialPort",
// "write msg error; path = " + portPath + ", error msg = " + e.message
// )
// e.printStackTrace()
// if (mAutoRetryConnect) {
// closePort()
// openSerialPort()
// }
// }
// }
// task.attachScheduler(mTaskScheduler)
// task.enqueue()
try { try {
val outputStream = helper?.outputStream() val outputStream = helper?.outputStream()
outputStream?.write(it) outputStream?.write(data)
outputStream?.flush() outputStream?.flush()
} catch (e: IOException) { } catch (e: IOException) {
Log.e( Log.e(
@ -84,9 +103,6 @@ class EasySerialPort<T>(
} }
} }
} }
task.attachScheduler(mTaskScheduler)
task.enqueue()
}
/** /**
* 开始自动重连 * 开始自动重连

@ -1,139 +0,0 @@
package com.common.serialport.utils;
import java.util.ArrayList;
import java.util.List;
/**
*
* Created by Administrator on 2016/6/2.
*/
public class DataUtils {
//-------------------------------------------------------
// 判断奇数或偶数位运算最后一位是1则为奇数为0是偶数
public static int isOdd(int num) {
return num & 1;
}
//-------------------------------------------------------
//Hex字符串转int
public static int HexToInt(String inHex) {
return Integer.parseInt(inHex, 16);
}
public static String IntToHex(int intHex){
return Integer.toHexString(intHex);
}
//-------------------------------------------------------
//Hex字符串转byte
public static byte HexToByte(String inHex) {
return (byte) Integer.parseInt(inHex, 16);
}
//-------------------------------------------------------
//1字节转2个Hex字符
public static String Byte2Hex(Byte inByte) {
return String.format("%02x", new Object[]{inByte}).toUpperCase();
}
//-------------------------------------------------------
//字节数组转转hex字符串
public static String ByteArrToHex(byte[] inBytArr) {
StringBuilder strBuilder = new StringBuilder();
for (byte valueOf : inBytArr) {
strBuilder.append(Byte2Hex(Byte.valueOf(valueOf)));
strBuilder.append(" ");
}
return strBuilder.toString();
}
//-------------------------------------------------------
//字节数组转转hex字符串可选长度
public static String ByteArrToHex(byte[] inBytArr, int offset, int byteCount) {
StringBuilder strBuilder = new StringBuilder();
int j = byteCount;
for (int i = offset; i < j; i++) {
strBuilder.append(Byte2Hex(Byte.valueOf(inBytArr[i])));
}
return strBuilder.toString();
}
//-------------------------------------------------------
//转hex字符串转字节数组
public static byte[] HexToByteArr(String inHex) {
byte[] result;
int hexlen = inHex.length();
if (isOdd(hexlen) == 1) {
hexlen++;
result = new byte[(hexlen / 2)];
inHex = "0" + inHex;
} else {
result = new byte[(hexlen / 2)];
}
int j = 0;
for (int i = 0; i < hexlen; i += 2) {
result[j] = HexToByte(inHex.substring(i, i + 2));
j++;
}
return result;
}
/**
*
*
* @param inputString
* @param length
* @return
*/
public static List<String> getDivLines(String inputString, int length) {
List<String> divList = new ArrayList<>();
int remainder = (inputString.length()) % length;
// 一共要分割成几段
int number = (int) Math.floor((inputString.length()) / length);
for (int index = 0; index < number; index++) {
String childStr = inputString.substring(index * length, (index + 1) * length);
divList.add(childStr);
}
if (remainder > 0) {
String cStr = inputString.substring(number * length, inputString.length());
divList.add(cStr);
}
return divList;
}
/**
*
*
* @param val value
* @return
*/
public static String twoByte(String val) {
if (val.length() > 4) {
val = val.substring(0, 4);
} else {
int l = 4 - val.length();
for (int i = 0; i < l; i++) {
val = "0" + val;
}
}
return val;
}
/**
*
*
* @param cmd
* @return
*/
public static String sum(String cmd) {
List<String> cmdList = DataUtils.getDivLines(cmd, 2);
int sumInt = 0;
for (String c : cmdList) {
sumInt += DataUtils.HexToInt(c);
}
String sum = DataUtils.IntToHex(sumInt);
sum = DataUtils.twoByte(sum);
cmd += sum;
return cmd.toUpperCase();
}
}

@ -0,0 +1,146 @@
package com.common.serialport.utils;
/**
*
*/
public class HexUtils {
/**
* 10
*
* @param num
* @return
*/
static public int isOdd(int num) {
return num & 0x1;
}
/**
* HexLong
*
* @param inHex
* @return
*/
static public long hexToLong(String inHex) {
return Long.parseLong(inHex, 16);
}
/**
* Hexbyte
*
* @param inHex
* @return
*/
static public byte hexToByte(String inHex)//
{
return (byte) Integer.parseInt(inHex, 16);
}
/**
* 1 2Hex
*
* @param inByte
* @return
*/
static public String byte2Hex(Byte inByte) {
return String.format("%02x", inByte).toUpperCase();
}
/**
* hex
*
* @param formatStr 1"%02x" 2"%04x"
* @param num
* @return
*/
static public String num2Hex(String formatStr, long num) {
return String.format(formatStr, num).toUpperCase();
}
/**
* hex
*
* @param inBytArr
* @return
*/
static public String byteArrToHex(byte[] inBytArr) {
StringBuilder strBuilder = new StringBuilder();
int j = inBytArr.length;
for (int i = 0; i < j; i++) {
strBuilder.append(byte2Hex(inBytArr[i]));
strBuilder.append(" ");
}
return strBuilder.toString();
}
/**
* hex
*
* @param inBytArr
* @param offset
* @param end
* @return
*/
static public String byteArrToHex(byte[] inBytArr, int offset, int end) {
StringBuilder strBuilder = new StringBuilder();
int j = end;
for (int i = offset; i < j; i++) {
strBuilder.append(byte2Hex(inBytArr[i]));
}
return strBuilder.toString();
}
/**
*
*
* @param inBytArr
* @param offset
* @param byteCount
* @return
*/
static public String byteArrToStr(byte[] inBytArr, int offset, int byteCount) {
byte[] array = new byte[byteCount - offset];
System.arraycopy(inBytArr, offset, array, 0, byteCount - offset);
return new String(array);
}
/**
* hex
*
* @param inHex
* @return
*/
static public byte[] hexToByteArr(String inHex)//hex字符串转字节数组
{
int hexlen = inHex.length();
byte[] result;
if (isOdd(hexlen) == 1) {//奇数
hexlen++;
result = new byte[(hexlen / 2)];
inHex = "0" + inHex;
} else {//偶数
result = new byte[(hexlen / 2)];
}
int j = 0;
for (int i = 0; i < hexlen; i += 2) {
result[j] = hexToByte(inHex.substring(i, i + 2));
j++;
}
return result;
}
/**
* 16
*
* @param inHex
* @return
*/
static public String reverseHexStr(String inHex) {
int hexlen = inHex.length();
StringBuilder stringBuilder = new StringBuilder();
for (int i = hexlen; i >= 2; i -= 2) {
stringBuilder.append(inHex.substring(i - 2, i));
}
return stringBuilder.toString();
}
}
Loading…
Cancel
Save