desc:气体单位转换功能

main
xiaowusky 2 years ago
parent ae262075c6
commit b54b850a5b

@ -82,12 +82,16 @@ fun getGasHighThreshold(gasType: String): Float {
}
const val UNIT_VOL = "%VOL"
const val UNIT_PPM = "ppm"
const val UNIT_MGM3 = "mg/m3"
/**
* 获取本地气体单位
*/
fun getLocalGasUnit(gasType: String): String {
return when (gasType.uppercase()) {
O2 -> "%VOL"
O2 -> UNIT_VOL
CO, CH4, H2S -> getDefaultUnit(gasType)
else -> ""
}
@ -98,5 +102,72 @@ private fun getDefaultUnit(gasType: String): String {
if (!localUnit.isNullOrEmpty()) {
return localUnit
}
return "ppm"
return UNIT_PPM
}
fun saveGasUnit(gasType: String, unit: String) {
MMKVUtils.put("unit_$gasType", unit)
}
/**
* ppm单位的气体量程
*/
val gas_range_ppm = hashMapOf<String, String>(
Pair(CO, "0-1000 $UNIT_PPM"),
Pair(CH4, "0-50000 $UNIT_PPM"),
Pair(H2S, "0-100 $UNIT_PPM")
)
/**
* mg/m3单位的气体量程
*
* ppm -> mg/m3 X=M.C/22.4
* X污染物以每标立方米的毫克数表示的浓度值
* C污染物以 ppm 表示的浓度值
* M污染物的分之子量
*
* CO分子量 = 28 28/22.4 * 1000
* CH4分子量 = 16 16/22.4 * 50000
* H2S分子量 = 34 34/22.4 * 100
*/
val gas_range_mgm3 = hashMapOf<String, String>(
Pair(CO, "0-1250 $UNIT_MGM3"),
Pair(CH4, "0-35714 $UNIT_MGM3"),
Pair(H2S, "0-151 $UNIT_MGM3")
)
/**
* 气体分子质量
*/
const val MOLECULAR_CO = 28
const val MOLECULAR_H2S = 34
const val MOLECULAR_CH4 = 16
/**
* 氧气的量程
*/
const val O2_RANGE = "0-30 $UNIT_VOL"
/**
* 获取气体传感器量程
*/
fun getGasRange(gasType: String, gasUnit: String): String {
if (gasType == O2) {
return O2_RANGE
} else {
if (gasUnit == UNIT_PPM) {
return gas_range_ppm[gasType] ?: ""
} else if (gasUnit == UNIT_MGM3) {
return gas_range_mgm3[gasType] ?: ""
}
}
return ""
}
fun ppm2mgm3(ppmValue: Double, molecular: Int): Double {
return ppmValue * molecular / 22.4
}
fun ch4Lel2ppm(lelValue: Double): Double {
return lelValue * 10000 / 20.0
}

@ -6,7 +6,6 @@ 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.Warning
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
@ -33,8 +32,6 @@ object ParseHelper {
DevicesApi()
}
private val gasMap = hashMapOf<String, String>()
private val gasUnitMap = hashMapOf<String, String>()
fun parse(it: ByteArray) {
try {
@ -106,22 +103,23 @@ object ParseHelper {
c18.plus(c17).plus(java.lang.Long.toBinaryString(valueHexLong)).toInt(2) / 10.0.pow(
pointNum
)
if (gasType.uppercase() == "CH4") {
value = value / 20.0 * 10000
LogUtils.v("receive msg $gasType, 浓度 = $c18$c17, | $valueHex, $valueHexLong, | $value ppm")
} else {
LogUtils.v("receive msg $gasType, 浓度 = $c18$c17, | $valueHex, $valueHexLong, | $value $unit")
}
// 量程
val rangHex: String = HexUtils.byteArrToHex(it, 11, 11 + 2)
val rangHexLong: Long = HexUtils.hexToLong(rangHex)
LogUtils.w("receive msg 单位转换前 $gasType, 浓度 = $value $unit")
//根据单位进行数值转换
val localGasUnit = getLocalGasUnit(gasType)
if (localGasUnit != unit) {
value = convertData(gasType, value, unit, localGasUnit)
LogUtils.w("receive msg 单位转换后 $gasType, 浓度 = $value $localGasUnit")
}
// 存储临时数据
gasMap[gasType] = "$value "
gasUnitMap[gasType] = "$unit"
gasMap[gasType] = " : $value $localGasUnit"
// 插入
insertGasData(gasType, value, unit, rangHexLong)
insertGasData(gasType, value, localGasUnit)
}
private fun setOverlayData() {
@ -132,16 +130,16 @@ object ParseHelper {
val builder: StringBuilder = java.lang.StringBuilder()
valueCo?.let {
builder.append(CO).append(" : ").append(valueCo).append(gasUnitMap[CO]).append("@")
builder.append(CO).append(valueCo).append("@")
}
valueCH4?.let {
builder.append(CH4).append(" : ").append(valueCH4).append("ppm").append("@")
builder.append(CH4).append(valueCH4).append("@")
}
valueO2?.let {
builder.append(O2).append(" : ").append(valueO2).append(gasUnitMap[O2]).append("@")
builder.append(O2).append(valueO2).append("@")
}
valueH2S?.let {
builder.append(H2S).append(" : ").append(valueH2S).append(gasUnitMap[H2S])
builder.append(H2S).append(valueH2S)
}
TxtOverlay.setShowTip(builder.toString())
}
@ -149,15 +147,12 @@ object ParseHelper {
/**
* 插入气体数据
*/
private fun insertGasData(gasType: String, value: Double, unit: String, rangHexLong: Long) {
private fun insertGasData(gasType: String, value: Double, unit: String) {
GlobalScope.launch {
// 阈值范围
val min = getGasLowThreshold(gasType).toDouble()
val max = getGasHighThreshold(gasType).toDouble()
// 存储量程最大值
MMKVUtils.put("range_${gasType}", "0$unit~$rangHexLong$unit")
// 构造气体数据
val timeMillis = System.currentTimeMillis()
val gas = Gas(timeMillis, gasType, value, unit, min, max)
@ -248,4 +243,33 @@ object ParseHelper {
updateGasTypeDb(gasName, GasPortStatus.OUTLINE)
}
}
/**
* 气体浓度 单位转换
* 氧气O2单位固定不用转换
* 其他三种气体可能需要转换
*/
private fun convertData(
gasType: String,
value: Double,
unit: String,
localGasUnit: String
): Double {
var retValue = value
if (CH4 == gasType) {
retValue = ch4Lel2ppm(value)
if (UNIT_MGM3 == localGasUnit) {
retValue = ppm2mgm3(retValue, MOLECULAR_CH4)
}
} else if (H2S == gasType) {
if (UNIT_MGM3 == localGasUnit) {
retValue = ppm2mgm3(retValue, MOLECULAR_H2S)
}
} else if (CO == gasType) {
if (UNIT_MGM3 == localGasUnit) {
retValue = ppm2mgm3(retValue, MOLECULAR_CO)
}
}
return retValue
}
}

@ -5,10 +5,15 @@ 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.port.UNIT_MGM3
import com.yinuo.safetywatcher.watcher.port.UNIT_PPM
import com.yinuo.safetywatcher.watcher.port.cmd.O2
import com.yinuo.safetywatcher.watcher.port.getGasRange
import com.yinuo.safetywatcher.watcher.port.getLocalGasUnit
import com.yinuo.safetywatcher.watcher.port.saveGasUnit
import com.yinuo.safetywatcher.watcher.utils.hideIme
import com.yinuo.safetywatcher.watcher.utils.showIme
import com.yinuo.safetywatcher.watcher.utils.showToast
@ -32,16 +37,40 @@ class SensorSettingActivity : NoOptionsActivity() {
override fun initView() {
gasName = intent.getStringExtra("GasType")!!
val range = MMKVUtils.getString("range_${gasName}")
val localGasUnit = getLocalGasUnit(gasName)
// 氧气单位固定
if (gasName == O2) {
mBinding.rgUnit.visibility = View.GONE
mBinding.rbVol.visibility = View.VISIBLE
} else {
mBinding.rgUnit.visibility = View.VISIBLE
mBinding.rbVol.visibility = View.GONE
if (localGasUnit == UNIT_PPM) {
mBinding.rbPpm.isChecked = true
} else {
mBinding.rbMgm3.isChecked = true
}
}
// 昵称和量程
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")
val gasRange = getGasRange(gasName, localGasUnit)
mBinding.etStep.text = getString(R.string.sensor_step_txt).plus(": $gasRange")
}
// 设置各种监听
setListener()
}
private fun setListener() {
/**
* 跳转告警设置
*/
mBinding.tvWarnSetting.setOnClickListener {
val intent = Intent(
this@SensorSettingActivity,
@ -51,6 +80,9 @@ class SensorSettingActivity : NoOptionsActivity() {
startActivity(intent)
}
/**
* 昵称edittext按键设置
*/
mBinding.etName.setOnKeyListener { _, keyCode, event ->
if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
if (event.action == KeyEvent.ACTION_DOWN) {
@ -78,6 +110,21 @@ class SensorSettingActivity : NoOptionsActivity() {
}
mBinding.tvSave.setOnClickListener {
saveSetting()
}
mBinding.rgUnit.setOnCheckedChangeListener { _, checkedId ->
if (checkedId == R.id.rb_ppm) {
val gasRange = getGasRange(gasName, UNIT_PPM)
mBinding.etStep.text = getString(R.string.sensor_step_txt).plus(": $gasRange")
} else if (checkedId == R.id.rb_mgm3) {
val gasRange = getGasRange(gasName, UNIT_MGM3)
mBinding.etStep.text = getString(R.string.sensor_step_txt).plus(": $gasRange")
}
}
}
private fun saveSetting() {
val nickName = mBinding.etName.text.toString()
if (!nickName.isNullOrEmpty()) {
GlobalScope.launch {
@ -89,7 +136,12 @@ class SensorSettingActivity : NoOptionsActivity() {
}
}
}
showToast("保存成功")
val checkedRadioButtonId = mBinding.rgUnit.checkedRadioButtonId
var selectedUnit = UNIT_PPM
if (checkedRadioButtonId == R.id.rb_mgm3) {
selectedUnit = UNIT_MGM3
}
saveGasUnit(gasName, selectedUnit)
showToast("保存成功")
}
}

@ -33,6 +33,58 @@
android:paddingStart="@dimen/_30dp"
android:background="@drawable/cloud_sync_btn_bg"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/_6dp"
android:layout_marginTop="@dimen/_40dp"
android:text="@string/gas_unit"
android:textColor="@color/white"
android:textSize="@dimen/_30dp" />
<androidx.appcompat.widget.AppCompatRadioButton
android:id="@+id/rb_vol"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/_40dp"
android:layout_marginStart="@dimen/_20dp"
android:paddingHorizontal="@dimen/_6dp"
android:checked="true"
android:focusable="true"
android:text="@string/unit_vol"
android:textColor="@color/white"
android:textSize="@dimen/_28dp" />
<RadioGroup
android:id="@+id/rg_unit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/_40dp"
android:layout_marginStart="@dimen/_20dp"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatRadioButton
android:id="@+id/rb_ppm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="@dimen/_6dp"
android:focusable="true"
android:text="@string/unit_ppm"
android:textColor="@color/white"
android:textSize="@dimen/_28dp" />
<androidx.appcompat.widget.AppCompatRadioButton
android:id="@+id/rb_mgm3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="@dimen/_6dp"
android:focusable="true"
android:text="@string/unit_mg_m3"
android:textColor="@color/white"
android:layout_marginStart="@dimen/_40dp"
android:textSize="@dimen/_28dp" />
</RadioGroup>
<!--<RelativeLayout
android:layout_width="@dimen/_600dp"
android:layout_height="@dimen/_100dp"

@ -66,4 +66,8 @@
<string name="confirm_clear_data_tip">确定恢复出厂设置?</string>
<string name="low_threshold">低报警值(单位:</string>
<string name="high_threshold">高报警值(单位:</string>
<string name="gas_unit">气体单位</string>
<string name="unit_ppm">ppm</string>
<string name="unit_mg_m3">mg/m3</string>
<string name="unit_vol">%VOL</string>
</resources>

Loading…
Cancel
Save