diff --git a/app/build.gradle b/app/build.gradle index 7f379c8..d862be0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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 { enabled = true } + buildTypes { + debug { + signingConfig signingConfigs.debug + } + release { + signingConfig signingConfigs.release + } + } } @@ -69,4 +92,6 @@ dependencies { annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.0.0' implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0' + + implementation 'com.aill:AndroidSerialPort:1.0.8' } diff --git a/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt b/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt index 9e0ecd7..ab987f5 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt @@ -34,18 +34,6 @@ object TestUtils { TxtOverlay.setShowTip("co2:50%@co:44%") PushHelper.setPushUrl("rtsp://192.168.5.17:554/123") GlobalScope.launch() { - // 插入类型 - val typeDao = DBUtils.gasTypeDao() - val all = typeDao.getAll() - if (all.isNotEmpty()) { - return@launch - } - val list = mutableListOf() - list.add(GasType("CO", "", false)) - list.add(GasType("CO2", "", false)) - list.add(GasType("O2", "", false)) - typeDao.insertAll(list) - // 构造气体数据 val timeMillis = System.currentTimeMillis() diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/App.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/App.kt index 89e287b..7b5b4a0 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/App.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/App.kt @@ -4,12 +4,12 @@ import com.common.commonlib.CommonApplication import com.common.commonlib.db.DBUtils import com.common.commonlib.db.dao.WarningDao import com.common.commonlib.db.entity.Warning -import com.lztek.toolkit.Lztek import com.yinuo.safetywatcher.TestUtils import com.yinuo.safetywatcher.watcher.constant.CAMERA_DNS import com.yinuo.safetywatcher.watcher.constant.CAMERA_GATEWAY import com.yinuo.safetywatcher.watcher.constant.CAMERA_IP 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.wifi.WiFiConfig import com.yinuo.safetywatcher.watcher.wifi.WiFiModule @@ -23,7 +23,7 @@ import java.io.File class App : CommonApplication() { override fun onCreate() { super.onCreate() - LztekUtil.setObject(Lztek.create(this)) +// LztekUtil.setObject(Lztek.create(this)) ipConfig() wifiConfig() tryFixDbData() @@ -73,7 +73,7 @@ class App : CommonApplication() { val gasTypeDao = DBUtils.gasTypeDao() val all = gasTypeDao.getAll() all.onEach { gasType -> - gasType.online = false + gasType.status = GasPortStatus.OUTLINE gasTypeDao.insert(gasType) } }.await() diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/GasUtils.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/GasUtils.kt index 0ca418d..5715232 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/GasUtils.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/GasUtils.kt @@ -1,24 +1,20 @@ 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.yinuo.library.vlc.TxtOverlay +import com.common.serialport.ComMultiPortUtils +import com.yinuo.safetywatcher.watcher.port.cmd.CMD import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.Runnable import kotlinx.coroutines.delay import kotlinx.coroutines.launch object GasUtils { private const val BAUD_RATE = 9600 - private const val FULL_MSG_SIZE = 9 - private const val CHECK_TIME = 10000L - private val mPortFlags = booleanArrayOf(false, false, false, false) - private val mPortRunnable = hashMapOf() - private val mHandler = Handler(Looper.getMainLooper()) + private const val PORT_PATH = "/dev/ttyS1" + const val FULL_MSG_SIZE = 9 + const val CHECK_TIME = 10000L + private const val READ_MSG_INTERVAL = 500L + private var mInitFlag = false fun initPort() { openPorts() @@ -26,56 +22,32 @@ object GasUtils { } private fun openPorts() { - if (!mPortFlags[0]) { - PlatformMultiPortUtils.openPort("/dev/tyyS0", BAUD_RATE) { - if (it.isNotEmpty() && it.size >= 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("") - } - } + if (!mInitFlag) { + ComMultiPortUtils.openPort(PORT_PATH, BAUD_RATE) { + mInitFlag = true + ParseHelper.parse(it) } - } - if (!mPortFlags[1]) { - PlatformMultiPortUtils.openPort("/dev/tyyS1", BAUD_RATE) {} - } - if (!mPortFlags[2]) { - PlatformMultiPortUtils.openPort("/dev/tyyS2", BAUD_RATE) {} - } - if (!mPortFlags[3]) { - PlatformMultiPortUtils.openPort("/dev/tyyS3", BAUD_RATE) {} + readGasMsg() } } - @OptIn(DelicateCoroutinesApi::class) - private fun updateGasTypeDb(gasName: Byte, port: String, online: Boolean) { - GlobalScope.launch { - val typeDao = DBUtils.gasTypeDao() - val gasType = typeDao.getByName(gasName.toString()) - gasType?.online = online - typeDao.insert(gasType ?: GasType(gasName.toString(), port, online)) - } - } - - private fun setFlag(index: Int, gasName: Byte, port: String) { - var flagRunnable = mPortRunnable[index] - if (flagRunnable == null) { - flagRunnable = FlagRunnable(index, gasName, port) - mPortRunnable[index] = flagRunnable + /** + * 读取气体浓度 + */ + private fun readGasMsg() { + GlobalScope.launch(Dispatchers.IO) { + while (true) { + // 延时一段时间后,发送指令读取气体数据 + 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) + } } - 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) - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/ParseHelper.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/ParseHelper.kt new file mode 100644 index 0000000..9d39e78 --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/ParseHelper.kt @@ -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() + 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) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/CMD.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/CMD.kt new file mode 100644 index 0000000..06f517d --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/CMD.kt @@ -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() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/CRC.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/CRC.kt new file mode 100644 index 0000000..664ad40 --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/CRC.kt @@ -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] +} diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasAddress.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasAddress.kt new file mode 100644 index 0000000..8a043c9 --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasAddress.kt @@ -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 + } +} diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasPortStatus.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasPortStatus.kt new file mode 100644 index 0000000..3e7fd8b --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasPortStatus.kt @@ -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 + } +} diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasType.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasType.kt new file mode 100644 index 0000000..48d8c29 --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/GasType.kt @@ -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 "" +} diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/ResponseHelper.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/ResponseHelper.kt new file mode 100644 index 0000000..846e519 --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/cmd/ResponseHelper.kt @@ -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 -> "" + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/SensorAdapter.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/SensorAdapter.kt index 83fcca3..d73b252 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/SensorAdapter.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/SensorAdapter.kt @@ -7,6 +7,7 @@ import com.common.commonlib.db.entity.GasType import com.yinuo.safetywatcher.R import com.yinuo.safetywatcher.databinding.LayoutItemSensorBinding import com.yinuo.safetywatcher.watcher.base.BaseRvAdapter +import com.yinuo.safetywatcher.watcher.port.cmd.GasPortStatus import com.yinuo.safetywatcher.watcher.ui.SensorSettingActivity class SensorAdapter : @@ -35,17 +36,29 @@ class SensorAdapter : } binding.sensorName.text = data.nickName ?: "${data.type}传感器" - val state = data.online + val state = data.status binding.sensorStatus.text = context.getText(getShowStatus(state)) binding.sensorStatus.setTextColor(context.getColor(getShowStatusColor(state))) } - private fun getShowStatusColor(state: Boolean): Int { - return if (state) R.color.color_ok else R.color.color_error + private fun getShowStatusColor(state: Int): Int { + 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 { - return if (state) R.string.status_ok else R.string.status_offline + private fun getShowStatus(state: Int): Int { + 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 + } } } } diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 63095ab..537d65a 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -21,6 +21,7 @@ #202A45 #01E41C + #f6d365 #999999 #E40101 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 07cf0e2..a30fb8d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -31,6 +31,7 @@ 正常 离线 + 预热 故障 传感器报警值设定 保存 diff --git a/buildCommon/commonLibConfig.gradle b/buildCommon/commonLibConfig.gradle index 5ab29a3..4ef5b2a 100644 --- a/buildCommon/commonLibConfig.gradle +++ b/buildCommon/commonLibConfig.gradle @@ -1,6 +1,6 @@ project.ext { sign = [ - keystore_path : "../signature/innovationapp.jks", + keystore_path : "../innovationapp.jks", keystore_pwd : "123456", keystore_alias: "yinuo" ] diff --git a/innovationapp.jks b/innovationapp.jks new file mode 100644 index 0000000..20f47af Binary files /dev/null and b/innovationapp.jks differ diff --git a/library-common/src/main/java/com/common/commonlib/db/entity/GasType.kt b/library-common/src/main/java/com/common/commonlib/db/entity/GasType.kt index b95d07a..2266947 100644 --- a/library-common/src/main/java/com/common/commonlib/db/entity/GasType.kt +++ b/library-common/src/main/java/com/common/commonlib/db/entity/GasType.kt @@ -7,7 +7,6 @@ import androidx.room.PrimaryKey @Entity(tableName = "gas_type") data class GasType( @PrimaryKey @ColumnInfo(name = "gas_name") var type: String, - @ColumnInfo(name = "port_path") var port: String, - @ColumnInfo(name = "online_flag") var online: Boolean, + @ColumnInfo(name = "status") var status: Int = 3, @ColumnInfo(name = "nick_name") var nickName: String? = null, ) diff --git a/library-serialPort/src/main/java/com/common/serialport/EasySerialPort.kt b/library-serialPort/src/main/java/com/common/serialport/EasySerialPort.kt index f4cb2da..92c6830 100644 --- a/library-serialPort/src/main/java/com/common/serialport/EasySerialPort.kt +++ b/library-serialPort/src/main/java/com/common/serialport/EasySerialPort.kt @@ -42,13 +42,14 @@ class EasySerialPort( while (mStartReceiveMsg) { try { val ips = helper?.inputStream() - val readByte = ips?.available()?.let { ByteArray(it) } - readByte?.let { - val size = ips.read(it) + val readByte = ByteArray(25) + val size = ips?.read(readByte) + if (size != null) { if (size > 0) { mReceiver.invoke(readByte) } } + Thread.sleep(50L) } catch (e: IOException) { Log.e( "EasySerialPort", @@ -67,25 +68,40 @@ class EasySerialPort( * 写消息 */ open fun write(data: ByteArray) { - 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() - } +// 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 { + val outputStream = helper?.outputStream() + outputStream?.write(data) + 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() } /** diff --git a/library-serialPort/src/main/java/com/common/serialport/utils/DataUtils.java b/library-serialPort/src/main/java/com/common/serialport/utils/DataUtils.java deleted file mode 100644 index a5d45bd..0000000 --- a/library-serialPort/src/main/java/com/common/serialport/utils/DataUtils.java +++ /dev/null @@ -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 getDivLines(String inputString, int length) { - List 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 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(); - } -} diff --git a/library-serialPort/src/main/java/com/common/serialport/utils/HexUtils.java b/library-serialPort/src/main/java/com/common/serialport/utils/HexUtils.java new file mode 100644 index 0000000..e1aab3a --- /dev/null +++ b/library-serialPort/src/main/java/com/common/serialport/utils/HexUtils.java @@ -0,0 +1,146 @@ +package com.common.serialport.utils; + +/** + * 数据转换工具 + */ +public class HexUtils { + /** + * 判断奇数或偶数,位运算,最后一位是1则为奇数,为0是偶数 + * + * @param num + * @return + */ + static public int isOdd(int num) { + return num & 0x1; + } + + /** + * Hex字符串转Long + * + * @param inHex + * @return + */ + static public long hexToLong(String inHex) { + return Long.parseLong(inHex, 16); + } + + /** + * Hex字符串转byte + * + * @param inHex + * @return + */ + static public byte hexToByte(String inHex)// + { + return (byte) Integer.parseInt(inHex, 16); + } + + /** + * 1字节转 2个Hex字符 + * + * @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(); + } +} \ No newline at end of file