desc:解析传感器数据串联首页、水印

main
xiaowusky 2 years ago
parent 926bb54a18
commit 67fcf9885e

@ -37,28 +37,28 @@ object TestUtils {
// 构造气体数据 // 构造气体数据
val timeMillis = System.currentTimeMillis() val timeMillis = System.currentTimeMillis()
val gasDao = DBUtils.gasDao() // val gasDao = DBUtils.gasDao()
val gases = mutableListOf<Gas>() // val gases = mutableListOf<Gas>()
gases.add(Gas(timeMillis - 150 * 1000, "CO", 5.0)) // gases.add(Gas(timeMillis - 150 * 1000, "CO", 5.0))
gases.add(Gas(timeMillis - 150 * 1000, "O2", 5.0)) // gases.add(Gas(timeMillis - 150 * 1000, "O2", 5.0))
gases.add(Gas(timeMillis - 150 * 1000, "CO2", 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, "CO2", 4.0))
gases.add(Gas(timeMillis - 100 * 1000, "CO", 4.0)) // gases.add(Gas(timeMillis - 100 * 1000, "CO", 4.0))
gases.add(Gas(timeMillis - 100 * 1000, "O2", 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, "O2", 3.0))
gases.add(Gas(timeMillis - 45 * 1000, "CO", 3.0)) // gases.add(Gas(timeMillis - 45 * 1000, "CO", 3.0))
gases.add(Gas(timeMillis - 45 * 1000, "CO2", 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, "CO", 2.0))
gases.add(Gas(timeMillis - 30_000, "CO2", 2.0)) // gases.add(Gas(timeMillis - 30_000, "CO2", 2.0))
gases.add(Gas(timeMillis - 30_000, "O2", 2.0)) // gases.add(Gas(timeMillis - 30_000, "O2", 2.0))
//
gases.add(Gas(timeMillis, "CO", 1.0)) // gases.add(Gas(timeMillis, "CO", 1.0))
gases.add(Gas(timeMillis, "CO2", 1.0)) // gases.add(Gas(timeMillis, "CO2", 1.0))
gases.add(Gas(timeMillis, "O2", 1.0)) // gases.add(Gas(timeMillis, "O2", 1.0))
gasDao.insertAll(gases) // gasDao.insertAll(gases)
// 构造告警数据 // 构造告警数据
val warningDao = DBUtils.warningDao() val warningDao = DBUtils.warningDao()

@ -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
}

@ -11,7 +11,7 @@ import kotlinx.coroutines.launch
object GasUtils { object GasUtils {
private const val BAUD_RATE = 9600 private const val BAUD_RATE = 9600
private const val PORT_PATH = "/dev/ttyS1" private const val PORT_PATH = "/dev/ttyS1"
const val FULL_MSG_SIZE = 9 const val FULL_MSG_SIZE = 25
const val CHECK_TIME = 10000L const val CHECK_TIME = 10000L
private const val READ_MSG_INTERVAL = 500L private const val READ_MSG_INTERVAL = 500L
private var mInitFlag = false private var mInitFlag = false

@ -3,10 +3,19 @@ package com.yinuo.safetywatcher.watcher.port
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import com.common.commonlib.db.DBUtils import com.common.commonlib.db.DBUtils
import com.common.commonlib.db.entity.Gas
import com.common.commonlib.db.entity.GasType import com.common.commonlib.db.entity.GasType
import com.common.commonlib.utils.MMKVUtils
import com.common.serialport.utils.HexUtils import com.common.serialport.utils.HexUtils
import com.yinuo.library.vlc.TxtOverlay
import com.yinuo.library.vlc.utils.LogUtils 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.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.ResponseHelper
import com.yinuo.safetywatcher.watcher.port.cmd.getGasTypeByCode import com.yinuo.safetywatcher.watcher.port.cmd.getGasTypeByCode
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
@ -18,48 +27,45 @@ object ParseHelper {
private val mPortRunnable = hashMapOf<Int, FlagRunnable>() private val mPortRunnable = hashMapOf<Int, FlagRunnable>()
private val mHandler = Handler(Looper.getMainLooper()) private val mHandler = Handler(Looper.getMainLooper())
private val tempGasData = mutableListOf<Gas>()
private val devicesApi by lazy {
DevicesApi()
}
private val gasMap = hashMapOf<String, String>()
fun parse(it: ByteArray) { 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) { else -> {
// val checkSum = getCheckSum(it) LogUtils.v("unKnow status, do nothing")
// // 校验通过 }
// 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")
} }
} }
} catch (e: Exception) {
e.printStackTrace()
} }
} }
@ -71,7 +77,7 @@ object ParseHelper {
LogUtils.v("receive msg $gasType, unitBinaryString 1 = $unitBinaryString") LogUtils.v("receive msg $gasType, unitBinaryString 1 = $unitBinaryString")
if (unitBinaryString.length < 16) { if (unitBinaryString.length < 16) {
val offset = 16 - unitBinaryString.length val offset = 16 - unitBinaryString.length
repeat(offset){ repeat(offset) {
unitBinaryString = "0" + unitBinaryString; unitBinaryString = "0" + unitBinaryString;
} }
} }
@ -103,6 +109,59 @@ object ParseHelper {
val rangHex: String = HexUtils.byteArrToHex(it, 11, 11 + 2) val rangHex: String = HexUtils.byteArrToHex(it, 11, 11 + 2)
val rangHexLong: Long = HexUtils.hexToLong(rangHex) val rangHexLong: Long = HexUtils.hexToLong(rangHex)
LogUtils.v("receive msg, 量程 = $rangHex$rangHexLong") 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 { GlobalScope.launch {
val typeDao = DBUtils.gasTypeDao() val typeDao = DBUtils.gasTypeDao()
val gasType = typeDao.getByName(gasName) val gasType = typeDao.getByName(gasName)
gasType?.status = status
typeDao.insert(gasType ?: GasType(gasName, status)) typeDao.insert(gasType ?: GasType(gasName, status))
} }
} }

@ -1,11 +1,15 @@
package com.yinuo.safetywatcher.watcher.port.cmd 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) { enum class GasType(val code: Int, val desc: String) {
CO(5, "CO"), TYPE_CO(5, CO),
CH4(11, "CH4"), TYPE_CH4(11, CH4),
O2(67, "O2"), TYPE_O2(67, O2),
H2S(52, "H2S") TYPE_H2S(52, H2S)
} }
fun getGasTypeByCode(code: Int): String { fun getGasTypeByCode(code: Int): String {

@ -13,6 +13,7 @@ import com.yinuo.library.vlc.TxtOverlay
import com.yinuo.library.vlc.utils.LogUtils import com.yinuo.library.vlc.utils.LogUtils
import com.yinuo.safetywatcher.R import com.yinuo.safetywatcher.R
import com.yinuo.safetywatcher.databinding.ActivityHomeBinding import com.yinuo.safetywatcher.databinding.ActivityHomeBinding
import com.yinuo.safetywatcher.watcher.AppData
import com.yinuo.safetywatcher.watcher.base.NoOptionsActivity import com.yinuo.safetywatcher.watcher.base.NoOptionsActivity
import com.yinuo.safetywatcher.watcher.constant.CAMERA_URL import com.yinuo.safetywatcher.watcher.constant.CAMERA_URL
import com.yinuo.safetywatcher.watcher.constant.DELAY_TIME_CHECK_CAMERA import com.yinuo.safetywatcher.watcher.constant.DELAY_TIME_CHECK_CAMERA
@ -34,9 +35,6 @@ class HomeActivity : NoOptionsActivity() {
private var mRender: RtspSurfaceRender2? = null private var mRender: RtspSurfaceRender2? = null
private var mHasCameraData = false
private var mHasSensorData = false
override val isHome: Boolean override val isHome: Boolean
get() = true get() = true
@ -88,7 +86,7 @@ class HomeActivity : NoOptionsActivity() {
mRender?.setRtspUrl(CAMERA_URL) mRender?.setRtspUrl(CAMERA_URL)
mRender?.setFrameCallBack(object : IFrameCallBack { mRender?.setFrameCallBack(object : IFrameCallBack {
override fun onFrame() { override fun onFrame() {
mHasCameraData = true AppData.setCameraData(true)
changeViewStatus() changeViewStatus()
closeLoadingDialog() closeLoadingDialog()
watchCamera(DELAY_TIME_CHECK_CAMERA) watchCamera(DELAY_TIME_CHECK_CAMERA)
@ -106,12 +104,12 @@ class HomeActivity : NoOptionsActivity() {
lifecycleScope.launch(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.Main) {
//mHasSensorData = true //mHasSensorData = true
mBinding.errorView.visibility = mBinding.errorView.visibility =
if (!mHasCameraData) View.VISIBLE else View.GONE if (!AppData.hasCameraData()) View.VISIBLE else View.GONE
val errorRes = if (!mHasCameraData && !mHasSensorData) R.drawable.ic_nosingal else R.drawable.ic_icon val errorRes = if (!AppData.hasCameraData() && !AppData.hasSensorData()) R.drawable.ic_nosingal else R.drawable.ic_icon
mBinding.errorView.setImageResource(errorRes) mBinding.errorView.setImageResource(errorRes)
// tipView // 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()) mBinding.tipView.setImageBitmap(TxtOverlay.getOverlayBitmap())
} }
} }
@ -121,10 +119,10 @@ class HomeActivity : NoOptionsActivity() {
*/ */
private val reStartCamera: Runnable = Runnable { private val reStartCamera: Runnable = Runnable {
LogUtils.w("reStartCamera Runnable start") LogUtils.w("reStartCamera Runnable start")
mHasCameraData = false AppData.setCameraData(false)
changeViewStatus() changeViewStatus()
if (NetworkHelper.isNetworkConnect(this@HomeActivity)) { if (NetworkHelper.isNetworkConnect(this@HomeActivity)) {
if (!isLoadingShowing() && !mHasSensorData) { if (!isLoadingShowing() && !AppData.hasSensorData()) {
showLoadingDialog(R.string.connecting_camera) showLoadingDialog(R.string.connecting_camera)
} }
mRender?.reStart() mRender?.reStart()
@ -147,7 +145,7 @@ class HomeActivity : NoOptionsActivity() {
private fun setForSensor() { private fun setForSensor() {
TxtOverlay.setTipChangeListener { TxtOverlay.setTipChangeListener {
// 有传感器数据回调 // 有传感器数据回调
mHasSensorData = true AppData.setSensorData(true)
closeLoadingDialog() closeLoadingDialog()
changeViewStatus() changeViewStatus()
watchSensor(DELAY_TIME_CHECK_SENSOR) watchSensor(DELAY_TIME_CHECK_SENSOR)
@ -169,7 +167,7 @@ class HomeActivity : NoOptionsActivity() {
*/ */
private val watchSensorRunnable: Runnable = Runnable { private val watchSensorRunnable: Runnable = Runnable {
LogUtils.w("watchSensorRunnable start") LogUtils.w("watchSensorRunnable start")
mHasSensorData = false AppData.setSensorData(false)
changeViewStatus() changeViewStatus()
GasUtils.initPort() GasUtils.initPort()
watchSensor(DELAY_TIME_CHECK_SENSOR) watchSensor(DELAY_TIME_CHECK_SENSOR)

@ -9,6 +9,7 @@ import com.yinuo.safetywatcher.databinding.ActivitySensorBinding
import com.yinuo.safetywatcher.watcher.base.NoOptionsActivity import com.yinuo.safetywatcher.watcher.base.NoOptionsActivity
import com.yinuo.safetywatcher.watcher.ui.adapter.SensorAdapter import com.yinuo.safetywatcher.watcher.ui.adapter.SensorAdapter
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class SensorActivity : NoOptionsActivity() { class SensorActivity : NoOptionsActivity() {
@ -38,10 +39,13 @@ class SensorActivity : NoOptionsActivity() {
private fun queryData() { private fun queryData() {
lifecycleScope.launch { lifecycleScope.launch {
val gasTypeDao = DBUtils.gasTypeDao() while (true) {
val gasTypes = gasTypeDao.getAll() val gasTypeDao = DBUtils.gasTypeDao()
launch(Dispatchers.Main){ val gasTypes = gasTypeDao.getAll()
mAdapter.setData(gasTypes) launch(Dispatchers.Main) {
mAdapter.setData(gasTypes)
}
delay(5000L)
} }
} }
} }

@ -3,11 +3,16 @@ package com.yinuo.safetywatcher.watcher.ui
import android.content.Intent import android.content.Intent
import android.view.KeyEvent import android.view.KeyEvent
import android.view.View 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.R
import com.yinuo.safetywatcher.databinding.ActivitySensorSettingBinding import com.yinuo.safetywatcher.databinding.ActivitySensorSettingBinding
import com.yinuo.safetywatcher.watcher.base.NoOptionsActivity import com.yinuo.safetywatcher.watcher.base.NoOptionsActivity
import com.yinuo.safetywatcher.watcher.utils.hideIme import com.yinuo.safetywatcher.watcher.utils.hideIme
import com.yinuo.safetywatcher.watcher.utils.showIme import com.yinuo.safetywatcher.watcher.utils.showIme
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class SensorSettingActivity : NoOptionsActivity() { class SensorSettingActivity : NoOptionsActivity() {
private val mBinding by lazy { private val mBinding by lazy {
@ -23,6 +28,17 @@ class SensorSettingActivity : NoOptionsActivity() {
} }
override fun initView() { 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 { mBinding.tvWarnSetting.setOnClickListener {
startActivity( startActivity(
Intent( Intent(
@ -57,5 +73,19 @@ class SensorSettingActivity : NoOptionsActivity() {
mBinding.etName.hideIme() 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)
}
}
}
}
} }
} }

@ -6,7 +6,6 @@ import android.view.ViewGroup
import com.yinuo.safetywatcher.databinding.LayoutItemGasBinding import com.yinuo.safetywatcher.databinding.LayoutItemGasBinding
import com.yinuo.safetywatcher.watcher.base.BaseRvAdapter import com.yinuo.safetywatcher.watcher.base.BaseRvAdapter
import com.yinuo.safetywatcher.watcher.ui.ChartActivity import com.yinuo.safetywatcher.watcher.ui.ChartActivity
import com.yinuo.safetywatcher.watcher.ui.SensorSettingActivity
import com.yinuo.safetywatcher.watcher.utils.ChartBridge import com.yinuo.safetywatcher.watcher.utils.ChartBridge
class GasListAdapter : class GasListAdapter :

@ -32,7 +32,9 @@ class SensorAdapter :
binding.sensorSetting.performClick() binding.sensorSetting.performClick()
} }
binding.sensorSetting.setOnClickListener { 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}传感器" binding.sensorName.text = data.nickName ?: "${data.type}传感器"

@ -17,7 +17,7 @@ object TxtOverlay {
private var mLastShowTip = "" private var mLastShowTip = ""
// 待展示的提示文字 // 待展示的提示文字
private var mToDoShowTip = "1111111@2222222@333333" private var mToDoShowTip = ""
// 外部调用,设置待显示水印文字 // 外部调用,设置待显示水印文字
fun setShowTip(string: String) { fun setShowTip(string: String) {

Loading…
Cancel
Save