diff --git a/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt b/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt index ab987f5..05cefbe 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt @@ -37,28 +37,28 @@ object TestUtils { // 构造气体数据 val timeMillis = System.currentTimeMillis() - val gasDao = DBUtils.gasDao() - val gases = mutableListOf() - gases.add(Gas(timeMillis - 150 * 1000, "CO", 5.0)) - gases.add(Gas(timeMillis - 150 * 1000, "O2", 5.0)) - gases.add(Gas(timeMillis - 150 * 1000, "CO2", 5.0)) - - gases.add(Gas(timeMillis - 100 * 1000, "CO2", 4.0)) - gases.add(Gas(timeMillis - 100 * 1000, "CO", 4.0)) - gases.add(Gas(timeMillis - 100 * 1000, "O2", 4.0)) - - gases.add(Gas(timeMillis - 45 * 1000, "O2", 3.0)) - gases.add(Gas(timeMillis - 45 * 1000, "CO", 3.0)) - gases.add(Gas(timeMillis - 45 * 1000, "CO2", 3.0)) - - gases.add(Gas(timeMillis - 30_000, "CO", 2.0)) - gases.add(Gas(timeMillis - 30_000, "CO2", 2.0)) - gases.add(Gas(timeMillis - 30_000, "O2", 2.0)) - - gases.add(Gas(timeMillis, "CO", 1.0)) - gases.add(Gas(timeMillis, "CO2", 1.0)) - gases.add(Gas(timeMillis, "O2", 1.0)) - gasDao.insertAll(gases) +// val gasDao = DBUtils.gasDao() +// val gases = mutableListOf() +// gases.add(Gas(timeMillis - 150 * 1000, "CO", 5.0)) +// gases.add(Gas(timeMillis - 150 * 1000, "O2", 5.0)) +// gases.add(Gas(timeMillis - 150 * 1000, "CO2", 5.0)) +// +// gases.add(Gas(timeMillis - 100 * 1000, "CO2", 4.0)) +// gases.add(Gas(timeMillis - 100 * 1000, "CO", 4.0)) +// gases.add(Gas(timeMillis - 100 * 1000, "O2", 4.0)) +// +// gases.add(Gas(timeMillis - 45 * 1000, "O2", 3.0)) +// gases.add(Gas(timeMillis - 45 * 1000, "CO", 3.0)) +// gases.add(Gas(timeMillis - 45 * 1000, "CO2", 3.0)) +// +// gases.add(Gas(timeMillis - 30_000, "CO", 2.0)) +// gases.add(Gas(timeMillis - 30_000, "CO2", 2.0)) +// gases.add(Gas(timeMillis - 30_000, "O2", 2.0)) +// +// gases.add(Gas(timeMillis, "CO", 1.0)) +// gases.add(Gas(timeMillis, "CO2", 1.0)) +// gases.add(Gas(timeMillis, "O2", 1.0)) +// gasDao.insertAll(gases) // 构造告警数据 val warningDao = DBUtils.warningDao() diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/AppData.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/AppData.kt new file mode 100644 index 0000000..63758b8 --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/AppData.kt @@ -0,0 +1,20 @@ +package com.yinuo.safetywatcher.watcher + +object AppData { + // 是否有视频流数据 + private var mHasCameraData = false + // 是否有传感器数据 + private var mHasSensorData = false + + fun setCameraData(has: Boolean){ + this.mHasCameraData = has + } + + fun setSensorData(has: Boolean){ + this.mHasSensorData = has + } + + fun hasCameraData() = mHasCameraData + + fun hasSensorData() = mHasSensorData +} \ No newline at end of file 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 5715232..c8a3f44 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 @@ -11,7 +11,7 @@ import kotlinx.coroutines.launch object GasUtils { private const val BAUD_RATE = 9600 private const val PORT_PATH = "/dev/ttyS1" - const val FULL_MSG_SIZE = 9 + const val FULL_MSG_SIZE = 25 const val CHECK_TIME = 10000L private const val READ_MSG_INTERVAL = 500L private var mInitFlag = false 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 index 9d39e78..2fe0a9a 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/port/ParseHelper.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/port/ParseHelper.kt @@ -3,10 +3,19 @@ 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.Gas import com.common.commonlib.db.entity.GasType +import com.common.commonlib.utils.MMKVUtils import com.common.serialport.utils.HexUtils +import com.yinuo.library.vlc.TxtOverlay import com.yinuo.library.vlc.utils.LogUtils +import com.yinuo.safetywatcher.watcher.constant.GAS_CLOUD_UPLOAD_SIZE_ONCE +import com.yinuo.safetywatcher.watcher.net.DevicesApi +import com.yinuo.safetywatcher.watcher.port.cmd.CH4 +import com.yinuo.safetywatcher.watcher.port.cmd.CO import com.yinuo.safetywatcher.watcher.port.cmd.GasPortStatus +import com.yinuo.safetywatcher.watcher.port.cmd.H2S +import com.yinuo.safetywatcher.watcher.port.cmd.O2 import com.yinuo.safetywatcher.watcher.port.cmd.ResponseHelper import com.yinuo.safetywatcher.watcher.port.cmd.getGasTypeByCode import kotlinx.coroutines.DelicateCoroutinesApi @@ -18,48 +27,45 @@ object ParseHelper { private val mPortRunnable = hashMapOf() private val mHandler = Handler(Looper.getMainLooper()) + private val tempGasData = mutableListOf() + private val devicesApi by lazy { + DevicesApi() + } + private val gasMap = hashMapOf() fun parse(it: ByteArray) { + try { + if (it.isNotEmpty() && it.size >= GasUtils.FULL_MSG_SIZE) { + 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) + } - 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") + else -> { + LogUtils.v("unKnow status, do nothing") + } } } + } catch (e: Exception) { + e.printStackTrace() } } @@ -71,7 +77,7 @@ object ParseHelper { LogUtils.v("receive msg $gasType, unitBinaryString 1 = $unitBinaryString") if (unitBinaryString.length < 16) { val offset = 16 - unitBinaryString.length - repeat(offset){ + repeat(offset) { unitBinaryString = "0" + unitBinaryString; } } @@ -103,6 +109,59 @@ object ParseHelper { val rangHex: String = HexUtils.byteArrToHex(it, 11, 11 + 2) val rangHexLong: Long = HexUtils.hexToLong(rangHex) LogUtils.v("receive msg, 量程 = $rangHex,$rangHexLong") + + // 存储临时数据 + gasMap[gasType] = ": $value $unit" + // 插入 + insertGasData(gasType, value, unit, rangHexLong) + } + + private fun setOverlayData() { + val valueCo = gasMap[CO] + val valueCH4 = gasMap[CH4] + val valueO2 = gasMap[O2] + val valueH2S = gasMap[H2S] + + val builder: StringBuilder = java.lang.StringBuilder() + valueCo?.let { + builder.append(CO).append(valueCo).append("@") + } + valueCH4?.let { + builder.append(CH4).append(valueCH4).append("@") + } + valueO2?.let { + builder.append(O2).append(valueO2).append("@") + } + valueH2S?.let { + builder.append(H2S).append(valueH2S) + } + TxtOverlay.setShowTip(builder.toString()) + } + + /** + * 插入气体数据 + */ + private fun insertGasData(gasType: String, value: Double, unit: String, rangHexLong: Long) { + GlobalScope.launch { + // 设置水印数据 + setOverlayData() + + // 构造气体数据 + val timeMillis = System.currentTimeMillis() + val gas = Gas(timeMillis, gasType, value, unit) + + val gasDao = DBUtils.gasDao() + gasDao.insert(gas) + // 存储范围最大值 + MMKVUtils.put("range_${gasType}", "0$unit~$rangHexLong$unit") + + // 上传实时气体数据 + tempGasData.add(gas) + if (tempGasData.size > GAS_CLOUD_UPLOAD_SIZE_ONCE) { + devicesApi.uploadGasData(tempGasData) + tempGasData.clear() + } + } } /** @@ -113,6 +172,7 @@ object ParseHelper { GlobalScope.launch { val typeDao = DBUtils.gasTypeDao() val gasType = typeDao.getByName(gasName) + gasType?.status = status typeDao.insert(gasType ?: GasType(gasName, status)) } } 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 index 48d8c29..6596264 100644 --- 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 @@ -1,11 +1,15 @@ package com.yinuo.safetywatcher.watcher.port.cmd +const val CO = "CO" +const val CH4 = "CH4" +const val O2 = "O2" +const val H2S = "H2S" enum class GasType(val code: Int, val desc: String) { - CO(5, "CO"), - CH4(11, "CH4"), - O2(67, "O2"), - H2S(52, "H2S") + TYPE_CO(5, CO), + TYPE_CH4(11, CH4), + TYPE_O2(67, O2), + TYPE_H2S(52, H2S) } fun getGasTypeByCode(code: Int): String { diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/HomeActivity.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/HomeActivity.kt index 19a9745..3510c62 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/HomeActivity.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/HomeActivity.kt @@ -13,6 +13,7 @@ import com.yinuo.library.vlc.TxtOverlay import com.yinuo.library.vlc.utils.LogUtils import com.yinuo.safetywatcher.R import com.yinuo.safetywatcher.databinding.ActivityHomeBinding +import com.yinuo.safetywatcher.watcher.AppData import com.yinuo.safetywatcher.watcher.base.NoOptionsActivity import com.yinuo.safetywatcher.watcher.constant.CAMERA_URL import com.yinuo.safetywatcher.watcher.constant.DELAY_TIME_CHECK_CAMERA @@ -34,9 +35,6 @@ class HomeActivity : NoOptionsActivity() { private var mRender: RtspSurfaceRender2? = null - private var mHasCameraData = false - private var mHasSensorData = false - override val isHome: Boolean get() = true @@ -88,7 +86,7 @@ class HomeActivity : NoOptionsActivity() { mRender?.setRtspUrl(CAMERA_URL) mRender?.setFrameCallBack(object : IFrameCallBack { override fun onFrame() { - mHasCameraData = true + AppData.setCameraData(true) changeViewStatus() closeLoadingDialog() watchCamera(DELAY_TIME_CHECK_CAMERA) @@ -106,12 +104,12 @@ class HomeActivity : NoOptionsActivity() { lifecycleScope.launch(Dispatchers.Main) { //mHasSensorData = true mBinding.errorView.visibility = - if (!mHasCameraData) View.VISIBLE else View.GONE - val errorRes = if (!mHasCameraData && !mHasSensorData) R.drawable.ic_nosingal else R.drawable.ic_icon + if (!AppData.hasCameraData()) View.VISIBLE else View.GONE + val errorRes = if (!AppData.hasCameraData() && !AppData.hasSensorData()) R.drawable.ic_nosingal else R.drawable.ic_icon mBinding.errorView.setImageResource(errorRes) // tipView - mBinding.tipView.visibility = if (!mHasCameraData && mHasSensorData) View.VISIBLE else View.GONE + mBinding.tipView.visibility = if (!AppData.hasCameraData() && AppData.hasSensorData()) View.VISIBLE else View.GONE mBinding.tipView.setImageBitmap(TxtOverlay.getOverlayBitmap()) } } @@ -121,10 +119,10 @@ class HomeActivity : NoOptionsActivity() { */ private val reStartCamera: Runnable = Runnable { LogUtils.w("reStartCamera Runnable start") - mHasCameraData = false + AppData.setCameraData(false) changeViewStatus() if (NetworkHelper.isNetworkConnect(this@HomeActivity)) { - if (!isLoadingShowing() && !mHasSensorData) { + if (!isLoadingShowing() && !AppData.hasSensorData()) { showLoadingDialog(R.string.connecting_camera) } mRender?.reStart() @@ -147,7 +145,7 @@ class HomeActivity : NoOptionsActivity() { private fun setForSensor() { TxtOverlay.setTipChangeListener { // 有传感器数据回调 - mHasSensorData = true + AppData.setSensorData(true) closeLoadingDialog() changeViewStatus() watchSensor(DELAY_TIME_CHECK_SENSOR) @@ -169,7 +167,7 @@ class HomeActivity : NoOptionsActivity() { */ private val watchSensorRunnable: Runnable = Runnable { LogUtils.w("watchSensorRunnable start") - mHasSensorData = false + AppData.setSensorData(false) changeViewStatus() GasUtils.initPort() watchSensor(DELAY_TIME_CHECK_SENSOR) diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/SensorActivity.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/SensorActivity.kt index 3140efd..d945d4f 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/SensorActivity.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/SensorActivity.kt @@ -9,6 +9,7 @@ import com.yinuo.safetywatcher.databinding.ActivitySensorBinding import com.yinuo.safetywatcher.watcher.base.NoOptionsActivity import com.yinuo.safetywatcher.watcher.ui.adapter.SensorAdapter import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay import kotlinx.coroutines.launch class SensorActivity : NoOptionsActivity() { @@ -38,10 +39,13 @@ class SensorActivity : NoOptionsActivity() { private fun queryData() { lifecycleScope.launch { - val gasTypeDao = DBUtils.gasTypeDao() - val gasTypes = gasTypeDao.getAll() - launch(Dispatchers.Main){ - mAdapter.setData(gasTypes) + while (true) { + val gasTypeDao = DBUtils.gasTypeDao() + val gasTypes = gasTypeDao.getAll() + launch(Dispatchers.Main) { + mAdapter.setData(gasTypes) + } + delay(5000L) } } } diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/SensorSettingActivity.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/SensorSettingActivity.kt index 197b5bb..15ae1ca 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/SensorSettingActivity.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/SensorSettingActivity.kt @@ -3,11 +3,16 @@ package com.yinuo.safetywatcher.watcher.ui import android.content.Intent import android.view.KeyEvent import android.view.View +import androidx.lifecycle.lifecycleScope +import com.common.commonlib.db.DBUtils +import com.common.commonlib.utils.MMKVUtils import com.yinuo.safetywatcher.R import com.yinuo.safetywatcher.databinding.ActivitySensorSettingBinding import com.yinuo.safetywatcher.watcher.base.NoOptionsActivity import com.yinuo.safetywatcher.watcher.utils.hideIme import com.yinuo.safetywatcher.watcher.utils.showIme +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch class SensorSettingActivity : NoOptionsActivity() { private val mBinding by lazy { @@ -23,6 +28,17 @@ class SensorSettingActivity : NoOptionsActivity() { } override fun initView() { + val gasName = intent.getStringExtra("GasType")!! + val range = MMKVUtils.getString("range_${gasName}") + lifecycleScope.launch { + val typeDao = DBUtils.gasTypeDao() + val gasType = typeDao.getByName(gasName) + gasType?.nickName?.let { + mBinding.etName.setText(it) + } + mBinding.etStep.text = getString(R.string.sensor_step_txt).plus(": $range") + } + mBinding.tvWarnSetting.setOnClickListener { startActivity( Intent( @@ -57,5 +73,19 @@ class SensorSettingActivity : NoOptionsActivity() { mBinding.etName.hideIme() } } + + mBinding.tvSave.setOnClickListener { + val nickName = mBinding.etName.text.toString() + if (!nickName.isNullOrEmpty()) { + GlobalScope.launch { + val typeDao = DBUtils.gasTypeDao() + val gasType = typeDao.getByName(gasName) + gasType?.nickName = nickName + if (gasType != null) { + typeDao.insert(gasType) + } + } + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/GasListAdapter.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/GasListAdapter.kt index 513f001..712e091 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/GasListAdapter.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/GasListAdapter.kt @@ -6,7 +6,6 @@ import android.view.ViewGroup import com.yinuo.safetywatcher.databinding.LayoutItemGasBinding import com.yinuo.safetywatcher.watcher.base.BaseRvAdapter import com.yinuo.safetywatcher.watcher.ui.ChartActivity -import com.yinuo.safetywatcher.watcher.ui.SensorSettingActivity import com.yinuo.safetywatcher.watcher.utils.ChartBridge class GasListAdapter : 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 d73b252..16c6e64 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 @@ -32,7 +32,9 @@ class SensorAdapter : binding.sensorSetting.performClick() } binding.sensorSetting.setOnClickListener { - context.startActivity(Intent(context, SensorSettingActivity::class.java)) + val intent = Intent(context, SensorSettingActivity::class.java) + intent.putExtra("GasType", data.type) + context.startActivity(intent) } binding.sensorName.text = data.nickName ?: "${data.type}传感器" diff --git a/library-vlc/src/main/java/com/yinuo/library/vlc/TxtOverlay.kt b/library-vlc/src/main/java/com/yinuo/library/vlc/TxtOverlay.kt index 17115b3..8abbedd 100644 --- a/library-vlc/src/main/java/com/yinuo/library/vlc/TxtOverlay.kt +++ b/library-vlc/src/main/java/com/yinuo/library/vlc/TxtOverlay.kt @@ -17,7 +17,7 @@ object TxtOverlay { private var mLastShowTip = "" // 待展示的提示文字 - private var mToDoShowTip = "1111111@2222222@333333" + private var mToDoShowTip = "" // 外部调用,设置待显示水印文字 fun setShowTip(string: String) {