diff --git a/app/src/main/java/com/casic/br/operationsite/extensions/ByteArray.kt b/app/src/main/java/com/casic/br/operationsite/extensions/ByteArray.kt new file mode 100644 index 0000000..9fe5d16 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/extensions/ByteArray.kt @@ -0,0 +1,62 @@ +package com.casic.br.operationsite.extensions + +import kotlin.experimental.and + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val i = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[i ushr 4] + hexChars[j * 2 + 1] = hexArray[i and 0x0F] + } + return String(hexChars) +} + +/** + * ByteArray转ASCII中文字符 + * */ +fun ByteArray.toAsciiCode(): String { + val builder = StringBuilder() + this.forEach { + builder.append(Char(it.toInt())) + } + return builder.toString() +} + +fun ByteArray.handleGasConcentration(): Int { + /** + * [1, 0, 0, 0, 13, 14] + * */ + //负值需要计算补码 + val x = if (this[1] < 0) { + this[1].toInt() and 0xFF + } else { + this[1].toInt() + } + val y = if (this[2] < 0) { + this[2].toInt() and 0xFF + } else { + this[2].toInt() + } + val z = if (this[3] < 0) { + this[3].toInt() and 0xFF + } else { + this[3].toInt() + } + return (x * 65536 + y * 256 + z) +} + +fun ByteArray.handleCpuTemperature(): Float { + //[1, -128, 24] + val x = this[0] and 0xFF.toByte() + val y = if (this[1] < 0) { + this[1].toInt() and 0xFF + } else { + this[1].toInt() + } + return (x * 256 + y) / 10f +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/extensions/ByteArray.kt b/app/src/main/java/com/casic/br/operationsite/extensions/ByteArray.kt new file mode 100644 index 0000000..9fe5d16 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/extensions/ByteArray.kt @@ -0,0 +1,62 @@ +package com.casic.br.operationsite.extensions + +import kotlin.experimental.and + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val i = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[i ushr 4] + hexChars[j * 2 + 1] = hexArray[i and 0x0F] + } + return String(hexChars) +} + +/** + * ByteArray转ASCII中文字符 + * */ +fun ByteArray.toAsciiCode(): String { + val builder = StringBuilder() + this.forEach { + builder.append(Char(it.toInt())) + } + return builder.toString() +} + +fun ByteArray.handleGasConcentration(): Int { + /** + * [1, 0, 0, 0, 13, 14] + * */ + //负值需要计算补码 + val x = if (this[1] < 0) { + this[1].toInt() and 0xFF + } else { + this[1].toInt() + } + val y = if (this[2] < 0) { + this[2].toInt() and 0xFF + } else { + this[2].toInt() + } + val z = if (this[3] < 0) { + this[3].toInt() and 0xFF + } else { + this[3].toInt() + } + return (x * 65536 + y * 256 + z) +} + +fun ByteArray.handleCpuTemperature(): Float { + //[1, -128, 24] + val x = this[0] and 0xFF.toByte() + val y = if (this[1] < 0) { + this[1].toInt() and 0xFF + } else { + this[1].toInt() + } + return (x * 256 + y) / 10f +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index d3c20a7..0e2034f 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -6,7 +6,15 @@ import android.os.IBinder import android.os.Message import android.util.Log +import com.casic.br.operationsite.extensions.handleCpuTemperature +import com.casic.br.operationsite.extensions.handleGasConcentration +import com.casic.br.operationsite.extensions.toHex +import com.casic.br.operationsite.fragments.BaseSettingsFragment +import com.casic.br.operationsite.fragments.MethaneMonitorFragment +import com.casic.br.operationsite.fragments.VoiceSettingsFragment +import com.casic.br.operationsite.utils.CommandCreator import com.casic.br.operationsite.utils.LocaleConstant +import com.pengxh.kt.lite.extensions.toAsciiCode import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener import com.pengxh.kt.lite.utils.socket.tcp.TcpClient @@ -22,11 +30,124 @@ override fun handleMessage(msg: Message): Boolean { when (msg.what) { + LocaleConstant.QUERY_METHANE_STATE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryMethaneState()) + } + LocaleConstant.OPEN_METHANE_CODE -> { + tcpClient.sendMessage(CommandCreator.openLaser()) + } + + LocaleConstant.CLOSE_METHANE_CODE -> { + tcpClient.sendMessage(CommandCreator.closeLaser()) + } + + LocaleConstant.QUERY_METHANE_THRESHOLD_CODE -> { + tcpClient.sendMessage(CommandCreator.queryMethaneThreshold()) + } + + LocaleConstant.UPDATE_GAS_THRESHOLD_CODE -> { + val threshold = msg.obj as Int + val thresholdCommand = CommandCreator.setThreshold(threshold) + tcpClient.sendMessage(thresholdCommand) + } + + LocaleConstant.QUERY_CPU_TEMPERATURE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryCpuTemperature()) + } + + LocaleConstant.QUERY_VOICE_VALUE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryVoiceValue()) + } + + LocaleConstant.INCREASE_VOICE_CODE -> { + tcpClient.sendMessage(CommandCreator.increaseVoice()) + } + + LocaleConstant.REDUCE_VOICE_CODE -> { + tcpClient.sendMessage(CommandCreator.reduceVoice()) + } + + LocaleConstant.QUERY_VOICE_MODE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryVoiceMode()) + } + + LocaleConstant.OPEN_LOCALE_MODE_CODE -> { + tcpClient.sendMessage(CommandCreator.openLocaleMode()) + } + + LocaleConstant.OPEN_REMOTE_MODE_CODE -> { + tcpClient.sendMessage(CommandCreator.openRemoteMode()) + } + + LocaleConstant.QUERY_ALARM_MODE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryAlarmMode()) + } + + LocaleConstant.OPEN_METHANE_ALARM_CODE -> { + tcpClient.sendMessage(CommandCreator.openMethaneAlarm()) + } + + LocaleConstant.CLOSE_METHANE_ALARM_CODE -> { + tcpClient.sendMessage(CommandCreator.closeMethaneAlarm()) + } + + LocaleConstant.QUERY_DEVICE_STATE_VOICE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryDeviceStateVoice()) + } + + LocaleConstant.OPEN_DEVICE_STATE_TIPS_CODE -> { + tcpClient.sendMessage(CommandCreator.openVoiceTips()) + } + + LocaleConstant.CLOSE_DEVICE_STATE_TIPS_CODE -> { + tcpClient.sendMessage(CommandCreator.closeVoiceTips()) + } + + LocaleConstant.QUERY_BOARD_CONFIG_CODE -> { + tcpClient.sendMessage(CommandCreator.queryControlBoardConfig()) + } + + LocaleConstant.QUERY_WIFI_CONFIG_CODE -> { + tcpClient.sendMessage(CommandCreator.queryWiFiConfig()) + } + + LocaleConstant.QUERY_IS_USE_AI_CODE -> { + tcpClient.sendMessage(CommandCreator.queryIsUseAI()) + } + + LocaleConstant.QUERY_SERVER_CONFIG_CODE -> { + tcpClient.sendMessage(CommandCreator.queryServerConfig()) + } + + LocaleConstant.SET_BOARD_WIFI_CONFIG_CODE -> { + val params = msg.obj as Array<*> + tcpClient.sendMessage( + CommandCreator.setWiFiConfig(params[0].toString(), params[1].toString()) + ) + } + + LocaleConstant.SET_BOARD_SERVER_CONFIG_CODE -> { + val params = msg.obj as Array<*> + tcpClient.sendMessage( + CommandCreator.setServerConfig(params[0].toString(), params[1].toString()) + ) + } } return true } + /** + * 甲烷查询 + * */ + private val methaneRunnable = object : Runnable { + override fun run() { + tcpClient.sendMessage(CommandCreator.queryMethane()) + // 每3s重复一次 + weakReferenceHandler?.postDelayed(this, 3 * 1000L) + } + } + override fun onCreate() { super.onCreate() weakReferenceHandler = WeakReferenceHandler(this) @@ -36,14 +157,18 @@ override fun onConnected() { ForegroundRunningService.weakReferenceHandler?.sendEmptyMessage(2024110501) + //定时查询甲烷浓度 + weakReferenceHandler?.post(methaneRunnable) } override fun onDisconnected() { ForegroundRunningService.weakReferenceHandler?.sendEmptyMessage(2024110502) + weakReferenceHandler?.removeCallbacks(methaneRunnable) } override fun onConnectFailed() { ForegroundRunningService.weakReferenceHandler?.sendEmptyMessage(2024110503) + weakReferenceHandler?.removeCallbacks(methaneRunnable) } override fun onMessageReceived(bytes: ByteArray?) { @@ -51,10 +176,175 @@ return } Log.d(kTag, bytes.contentToString()) + //根据帧头判断。不能直接转为ascii,因为有的协议返回的不是ascii,会报错 + val dataHeadArray = bytes.copyOfRange(0, 7) + if (dataHeadArray.contentEquals(byteArrayOf(71, 101, 116, 68, 97, 116, 97))) { + //GetData + val dataArray = bytes.copyOfRange(10, bytes.size) + val data = dataArray.toAsciiCode().trim() + + val weakReferenceHandler = BaseSettingsFragment.weakReferenceHandler ?: return + + //判断类型 + when (Char(bytes[8].toInt())) { + '1' -> { + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.BOARD_CONFIG_RESPONSE_CODE + message.obj = data + weakReferenceHandler.sendMessage(message) + } + + '2' -> { + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.WIFI_CONFIG_RESPONSE_CODE + message.obj = data + weakReferenceHandler.sendMessage(message) + } + + '4' -> { + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_IS_USE_AI_RESPONSE_CODE + message.obj = data + weakReferenceHandler.sendMessage(message) + } + + '5' -> { + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.SERVER_CONFIG_RESPONSE_CODE + message.obj = data + weakReferenceHandler.sendMessage(message) + } + } + } else if (dataHeadArray.contentEquals(byteArrayOf(83, 101, 116, 68, 97, 116, 97))) { + //SetData + val dataArray = bytes.copyOfRange(10, bytes.size) + val data = dataArray.toAsciiCode().trim() + + val weakReferenceHandler = BaseSettingsFragment.weakReferenceHandler ?: return + + when (Char(bytes[8].toInt())) { + '2' -> { + if (data == "ok") { + weakReferenceHandler.sendEmptyMessage(LocaleConstant.SET_BOARD_WIFI_CONFIG_RESPONSE_CODE) + } + } + + '5' -> { + if (data == "ok") { + weakReferenceHandler.sendEmptyMessage(LocaleConstant.SET_BOARD_SERVER_CONFIG_RESPONSE_CODE) + } + } + } + } else if (bytes.size == 13) { + //取前6位解析设备编号 + val deviceCode = bytes.take(6).toByteArray().toHex() + if (BaseSettingsFragment.weakReferenceHandler != null) { + val weakReferenceHandler = BaseSettingsFragment.weakReferenceHandler!! + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.DEVICE_RESPONSE_CODE + message.obj = deviceCode + weakReferenceHandler.sendMessage(message) + } + + //取数据类型标志位,根据标志位解析不同的数据 + when ((bytes[6].toInt() and 0xFF).toString(16).uppercase()) { + "AA" -> { + //甲烷浓度 + val dataArray = bytes.copyOfRange(7, bytes.size) + val concentration = dataArray.handleGasConcentration() + val weakReferenceHandler = MethaneMonitorFragment.weakReferenceHandler ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_METHANE_RESPONSE_CODE + message.obj = concentration + weakReferenceHandler.sendMessage(message) + } + + "BB" -> { + when ((bytes[9].toInt() and 0xFF).toString(16).uppercase()) { + "90" -> { + //语音源模式 + val weakReferenceHandler = VoiceSettingsFragment.weakReferenceHandler + ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_VOICE_MODE_RESPONSE_CODE + message.obj = bytes[10].toInt() + weakReferenceHandler.sendMessage(message) + } + + "91" -> { + //激光状态 + val weakReferenceHandler = MethaneMonitorFragment.weakReferenceHandler + ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_METHANE_STATE_RESPONSE_CODE + message.obj = bytes[10].toInt() + weakReferenceHandler.sendMessage(message) + } + + "92" -> { + //燃气报警开关 + val weakReferenceHandler = VoiceSettingsFragment.weakReferenceHandler + ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_ALARM_MODE_RESPONSE_CODE + message.obj = bytes[10].toInt() + weakReferenceHandler.sendMessage(message) + } + + "97" -> { + //设备状态语音提示开关 + val weakReferenceHandler = VoiceSettingsFragment.weakReferenceHandler + ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_DEVICE_STATE_VOICE_RESPONSE_CODE + message.obj = bytes[10].toInt() + weakReferenceHandler.sendMessage(message) + } + + "98" -> { + //音量调节 + if (bytes[8].toInt() == 1) { + val weakReferenceHandler = + VoiceSettingsFragment.weakReferenceHandler ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_VOICE_VALUE_RESPONSE_CODE + message.obj = bytes[10].toInt() + weakReferenceHandler.sendMessage(message) + } else { + Log.d(kTag, "onMessageReceived: 调节音量返回值不处理") + } + } + } + } + + "CC" -> { + //激光温度 + val dataArray = bytes.copyOfRange(10, bytes.size) + val weakReferenceHandler = MethaneMonitorFragment.weakReferenceHandler ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_CPU_TEMPERATURE_RESPONSE_CODE + message.obj = dataArray.handleCpuTemperature() + weakReferenceHandler.sendMessage(message) + } + } + } else if (bytes.size == 14) { + if ((bytes[6].toInt() and 0xFF).toString(16).uppercase() == "BB") { + if ((bytes[9].toInt() and 0xFF).toString(16).uppercase() == "94") { + val dataArray = bytes.copyOfRange(9, bytes.size) + val concentration = dataArray.handleGasConcentration() + val weakReferenceHandler = MethaneMonitorFragment.weakReferenceHandler ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_METHANE_THRESHOLD_RESPONSE_CODE + message.obj = concentration + weakReferenceHandler.sendMessage(message) + } + } + } } override fun onDestroy() { super.onDestroy() + weakReferenceHandler?.removeCallbacks(methaneRunnable) tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/extensions/ByteArray.kt b/app/src/main/java/com/casic/br/operationsite/extensions/ByteArray.kt new file mode 100644 index 0000000..9fe5d16 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/extensions/ByteArray.kt @@ -0,0 +1,62 @@ +package com.casic.br.operationsite.extensions + +import kotlin.experimental.and + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val i = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[i ushr 4] + hexChars[j * 2 + 1] = hexArray[i and 0x0F] + } + return String(hexChars) +} + +/** + * ByteArray转ASCII中文字符 + * */ +fun ByteArray.toAsciiCode(): String { + val builder = StringBuilder() + this.forEach { + builder.append(Char(it.toInt())) + } + return builder.toString() +} + +fun ByteArray.handleGasConcentration(): Int { + /** + * [1, 0, 0, 0, 13, 14] + * */ + //负值需要计算补码 + val x = if (this[1] < 0) { + this[1].toInt() and 0xFF + } else { + this[1].toInt() + } + val y = if (this[2] < 0) { + this[2].toInt() and 0xFF + } else { + this[2].toInt() + } + val z = if (this[3] < 0) { + this[3].toInt() and 0xFF + } else { + this[3].toInt() + } + return (x * 65536 + y * 256 + z) +} + +fun ByteArray.handleCpuTemperature(): Float { + //[1, -128, 24] + val x = this[0] and 0xFF.toByte() + val y = if (this[1] < 0) { + this[1].toInt() and 0xFF + } else { + this[1].toInt() + } + return (x * 256 + y) / 10f +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index d3c20a7..0e2034f 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -6,7 +6,15 @@ import android.os.IBinder import android.os.Message import android.util.Log +import com.casic.br.operationsite.extensions.handleCpuTemperature +import com.casic.br.operationsite.extensions.handleGasConcentration +import com.casic.br.operationsite.extensions.toHex +import com.casic.br.operationsite.fragments.BaseSettingsFragment +import com.casic.br.operationsite.fragments.MethaneMonitorFragment +import com.casic.br.operationsite.fragments.VoiceSettingsFragment +import com.casic.br.operationsite.utils.CommandCreator import com.casic.br.operationsite.utils.LocaleConstant +import com.pengxh.kt.lite.extensions.toAsciiCode import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener import com.pengxh.kt.lite.utils.socket.tcp.TcpClient @@ -22,11 +30,124 @@ override fun handleMessage(msg: Message): Boolean { when (msg.what) { + LocaleConstant.QUERY_METHANE_STATE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryMethaneState()) + } + LocaleConstant.OPEN_METHANE_CODE -> { + tcpClient.sendMessage(CommandCreator.openLaser()) + } + + LocaleConstant.CLOSE_METHANE_CODE -> { + tcpClient.sendMessage(CommandCreator.closeLaser()) + } + + LocaleConstant.QUERY_METHANE_THRESHOLD_CODE -> { + tcpClient.sendMessage(CommandCreator.queryMethaneThreshold()) + } + + LocaleConstant.UPDATE_GAS_THRESHOLD_CODE -> { + val threshold = msg.obj as Int + val thresholdCommand = CommandCreator.setThreshold(threshold) + tcpClient.sendMessage(thresholdCommand) + } + + LocaleConstant.QUERY_CPU_TEMPERATURE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryCpuTemperature()) + } + + LocaleConstant.QUERY_VOICE_VALUE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryVoiceValue()) + } + + LocaleConstant.INCREASE_VOICE_CODE -> { + tcpClient.sendMessage(CommandCreator.increaseVoice()) + } + + LocaleConstant.REDUCE_VOICE_CODE -> { + tcpClient.sendMessage(CommandCreator.reduceVoice()) + } + + LocaleConstant.QUERY_VOICE_MODE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryVoiceMode()) + } + + LocaleConstant.OPEN_LOCALE_MODE_CODE -> { + tcpClient.sendMessage(CommandCreator.openLocaleMode()) + } + + LocaleConstant.OPEN_REMOTE_MODE_CODE -> { + tcpClient.sendMessage(CommandCreator.openRemoteMode()) + } + + LocaleConstant.QUERY_ALARM_MODE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryAlarmMode()) + } + + LocaleConstant.OPEN_METHANE_ALARM_CODE -> { + tcpClient.sendMessage(CommandCreator.openMethaneAlarm()) + } + + LocaleConstant.CLOSE_METHANE_ALARM_CODE -> { + tcpClient.sendMessage(CommandCreator.closeMethaneAlarm()) + } + + LocaleConstant.QUERY_DEVICE_STATE_VOICE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryDeviceStateVoice()) + } + + LocaleConstant.OPEN_DEVICE_STATE_TIPS_CODE -> { + tcpClient.sendMessage(CommandCreator.openVoiceTips()) + } + + LocaleConstant.CLOSE_DEVICE_STATE_TIPS_CODE -> { + tcpClient.sendMessage(CommandCreator.closeVoiceTips()) + } + + LocaleConstant.QUERY_BOARD_CONFIG_CODE -> { + tcpClient.sendMessage(CommandCreator.queryControlBoardConfig()) + } + + LocaleConstant.QUERY_WIFI_CONFIG_CODE -> { + tcpClient.sendMessage(CommandCreator.queryWiFiConfig()) + } + + LocaleConstant.QUERY_IS_USE_AI_CODE -> { + tcpClient.sendMessage(CommandCreator.queryIsUseAI()) + } + + LocaleConstant.QUERY_SERVER_CONFIG_CODE -> { + tcpClient.sendMessage(CommandCreator.queryServerConfig()) + } + + LocaleConstant.SET_BOARD_WIFI_CONFIG_CODE -> { + val params = msg.obj as Array<*> + tcpClient.sendMessage( + CommandCreator.setWiFiConfig(params[0].toString(), params[1].toString()) + ) + } + + LocaleConstant.SET_BOARD_SERVER_CONFIG_CODE -> { + val params = msg.obj as Array<*> + tcpClient.sendMessage( + CommandCreator.setServerConfig(params[0].toString(), params[1].toString()) + ) + } } return true } + /** + * 甲烷查询 + * */ + private val methaneRunnable = object : Runnable { + override fun run() { + tcpClient.sendMessage(CommandCreator.queryMethane()) + // 每3s重复一次 + weakReferenceHandler?.postDelayed(this, 3 * 1000L) + } + } + override fun onCreate() { super.onCreate() weakReferenceHandler = WeakReferenceHandler(this) @@ -36,14 +157,18 @@ override fun onConnected() { ForegroundRunningService.weakReferenceHandler?.sendEmptyMessage(2024110501) + //定时查询甲烷浓度 + weakReferenceHandler?.post(methaneRunnable) } override fun onDisconnected() { ForegroundRunningService.weakReferenceHandler?.sendEmptyMessage(2024110502) + weakReferenceHandler?.removeCallbacks(methaneRunnable) } override fun onConnectFailed() { ForegroundRunningService.weakReferenceHandler?.sendEmptyMessage(2024110503) + weakReferenceHandler?.removeCallbacks(methaneRunnable) } override fun onMessageReceived(bytes: ByteArray?) { @@ -51,10 +176,175 @@ return } Log.d(kTag, bytes.contentToString()) + //根据帧头判断。不能直接转为ascii,因为有的协议返回的不是ascii,会报错 + val dataHeadArray = bytes.copyOfRange(0, 7) + if (dataHeadArray.contentEquals(byteArrayOf(71, 101, 116, 68, 97, 116, 97))) { + //GetData + val dataArray = bytes.copyOfRange(10, bytes.size) + val data = dataArray.toAsciiCode().trim() + + val weakReferenceHandler = BaseSettingsFragment.weakReferenceHandler ?: return + + //判断类型 + when (Char(bytes[8].toInt())) { + '1' -> { + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.BOARD_CONFIG_RESPONSE_CODE + message.obj = data + weakReferenceHandler.sendMessage(message) + } + + '2' -> { + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.WIFI_CONFIG_RESPONSE_CODE + message.obj = data + weakReferenceHandler.sendMessage(message) + } + + '4' -> { + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_IS_USE_AI_RESPONSE_CODE + message.obj = data + weakReferenceHandler.sendMessage(message) + } + + '5' -> { + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.SERVER_CONFIG_RESPONSE_CODE + message.obj = data + weakReferenceHandler.sendMessage(message) + } + } + } else if (dataHeadArray.contentEquals(byteArrayOf(83, 101, 116, 68, 97, 116, 97))) { + //SetData + val dataArray = bytes.copyOfRange(10, bytes.size) + val data = dataArray.toAsciiCode().trim() + + val weakReferenceHandler = BaseSettingsFragment.weakReferenceHandler ?: return + + when (Char(bytes[8].toInt())) { + '2' -> { + if (data == "ok") { + weakReferenceHandler.sendEmptyMessage(LocaleConstant.SET_BOARD_WIFI_CONFIG_RESPONSE_CODE) + } + } + + '5' -> { + if (data == "ok") { + weakReferenceHandler.sendEmptyMessage(LocaleConstant.SET_BOARD_SERVER_CONFIG_RESPONSE_CODE) + } + } + } + } else if (bytes.size == 13) { + //取前6位解析设备编号 + val deviceCode = bytes.take(6).toByteArray().toHex() + if (BaseSettingsFragment.weakReferenceHandler != null) { + val weakReferenceHandler = BaseSettingsFragment.weakReferenceHandler!! + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.DEVICE_RESPONSE_CODE + message.obj = deviceCode + weakReferenceHandler.sendMessage(message) + } + + //取数据类型标志位,根据标志位解析不同的数据 + when ((bytes[6].toInt() and 0xFF).toString(16).uppercase()) { + "AA" -> { + //甲烷浓度 + val dataArray = bytes.copyOfRange(7, bytes.size) + val concentration = dataArray.handleGasConcentration() + val weakReferenceHandler = MethaneMonitorFragment.weakReferenceHandler ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_METHANE_RESPONSE_CODE + message.obj = concentration + weakReferenceHandler.sendMessage(message) + } + + "BB" -> { + when ((bytes[9].toInt() and 0xFF).toString(16).uppercase()) { + "90" -> { + //语音源模式 + val weakReferenceHandler = VoiceSettingsFragment.weakReferenceHandler + ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_VOICE_MODE_RESPONSE_CODE + message.obj = bytes[10].toInt() + weakReferenceHandler.sendMessage(message) + } + + "91" -> { + //激光状态 + val weakReferenceHandler = MethaneMonitorFragment.weakReferenceHandler + ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_METHANE_STATE_RESPONSE_CODE + message.obj = bytes[10].toInt() + weakReferenceHandler.sendMessage(message) + } + + "92" -> { + //燃气报警开关 + val weakReferenceHandler = VoiceSettingsFragment.weakReferenceHandler + ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_ALARM_MODE_RESPONSE_CODE + message.obj = bytes[10].toInt() + weakReferenceHandler.sendMessage(message) + } + + "97" -> { + //设备状态语音提示开关 + val weakReferenceHandler = VoiceSettingsFragment.weakReferenceHandler + ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_DEVICE_STATE_VOICE_RESPONSE_CODE + message.obj = bytes[10].toInt() + weakReferenceHandler.sendMessage(message) + } + + "98" -> { + //音量调节 + if (bytes[8].toInt() == 1) { + val weakReferenceHandler = + VoiceSettingsFragment.weakReferenceHandler ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_VOICE_VALUE_RESPONSE_CODE + message.obj = bytes[10].toInt() + weakReferenceHandler.sendMessage(message) + } else { + Log.d(kTag, "onMessageReceived: 调节音量返回值不处理") + } + } + } + } + + "CC" -> { + //激光温度 + val dataArray = bytes.copyOfRange(10, bytes.size) + val weakReferenceHandler = MethaneMonitorFragment.weakReferenceHandler ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_CPU_TEMPERATURE_RESPONSE_CODE + message.obj = dataArray.handleCpuTemperature() + weakReferenceHandler.sendMessage(message) + } + } + } else if (bytes.size == 14) { + if ((bytes[6].toInt() and 0xFF).toString(16).uppercase() == "BB") { + if ((bytes[9].toInt() and 0xFF).toString(16).uppercase() == "94") { + val dataArray = bytes.copyOfRange(9, bytes.size) + val concentration = dataArray.handleGasConcentration() + val weakReferenceHandler = MethaneMonitorFragment.weakReferenceHandler ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_METHANE_THRESHOLD_RESPONSE_CODE + message.obj = concentration + weakReferenceHandler.sendMessage(message) + } + } + } } override fun onDestroy() { super.onDestroy() + weakReferenceHandler?.removeCallbacks(methaneRunnable) tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/CommandCreator.kt b/app/src/main/java/com/casic/br/operationsite/utils/CommandCreator.kt new file mode 100644 index 0000000..aadb0b7 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/utils/CommandCreator.kt @@ -0,0 +1,217 @@ +package com.casic.br.operationsite.utils + +object CommandCreator { + /** + * 查询激光状态 + * */ + fun queryMethaneState(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x01, 0x91.toByte(), 0x00, 0x00, 0x93.toByte()) + } + + /** + * 打开激光指令 + */ + fun openLaser(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x01, 0x00, 0x93.toByte()) + } + + /** + * 关闭激光指令 + */ + fun closeLaser(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x00, 0x00, 0x92.toByte()) + } + + /** + * 查询甲烷浓度指令 + */ + fun queryMethane(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x95.toByte(), 0x00, 0x00, 0x96.toByte()) + } + + /** + * 查询甲烷阈值指令 + * */ + fun queryMethaneThreshold(): ByteArray { + return byteArrayOf( + 0xAA.toByte(), + 0x01, + 0x01, + 0x94.toByte(), + 0x00, + 0x00, + 0x00, + 0x96.toByte() + ) + } + + /** + * 设置甲烷阈值指令 + */ + fun setThreshold(threshold: Int): ByteArray { + //数据位和校验位先都设置0x00占位 + val bytes = byteArrayOf( + 0xAA.toByte(), + 0x01, + 0x00, + 0x94.toByte(), + 0x00.toByte(), + 0x00.toByte(), + 0x00.toByte(), + 0x00.toByte() + ) + for (i in 0..255) { + for (j in 0..255) { + for (k in 0..255) { + //浓度值 = 数据码1 * 65536 + 数据码2 * 256 + 数据码3 + if (65536 * i + 256 * j + k == threshold) { + bytes[4] = i.toByte() + bytes[5] = j.toByte() + bytes[6] = k.toByte() + + //计算校验位。 + var sum = 0 + for (l in 1 until bytes.size - 1) { + sum += bytes[l] + } + bytes[7] = sum.toByte() + } + } + } + } + return bytes + } + + /** + * 查询甲烷芯片温度指令 + * */ + fun queryCpuTemperature(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x96.toByte(), 0x00, 0x00, 0x97.toByte()) + } + + /** + * 查询主控板主控板IP、子网掩码、网关IP指令 + * */ + fun queryControlBoardConfig(): ByteArray { + return "GetData:1\r\n".toByteArray() + } + + /** + * 查询是否和一体机一起使用指令 + * */ + fun queryIsUseAI(): ByteArray { + return "GetData:4\r\n".toByteArray() + } + + /** + * 安全树主控板要连接的远程服务器IP、端口号指令 + * */ + fun queryServerConfig(): ByteArray { + return "GetData:5\r\n".toByteArray() + } + + /** + * 设置主控板WiFi配置指令 + * */ + fun setWiFiConfig(wifiName: String, password: String): ByteArray { + return "SetData:2,${wifiName},${password}\r\n".toByteArray() + } + + /** + * 查询主控板WiFi配置指令 + * */ + fun queryWiFiConfig(): ByteArray { + return "GetData:2\r\n".toByteArray() + } + + /** + * 设置主控板服务地址指令 + * */ + fun setServerConfig(host: String, port: String): ByteArray { + return "SetData:5,${host},${port}\r\n".toByteArray() + } + + /** + * 查询音量值 + * */ + fun queryVoiceValue(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x01, 0x98.toByte(), 0x00, 0x00, 0x9A.toByte()) + } + + /** + * 音量增大指令 + * */ + fun increaseVoice(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x98.toByte(), 0x01, 0x00, 0x9A.toByte()) + } + + /** + * 音量减小指令 + * */ + fun reduceVoice(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x98.toByte(), 0x00, 0x00, 0x99.toByte()) + } + + /** + * 查询语音模式指令 + * */ + fun queryVoiceMode(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x01, 0x90.toByte(), 0x00, 0x00, 0x92.toByte()) + } + + /** + * 切换本地音源指令 + * */ + fun openLocaleMode(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x90.toByte(), 0x00, 0x00, 0x91.toByte()) + } + + /** + * 切换远程音源指令 + * */ + fun openRemoteMode(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x90.toByte(), 0x01, 0x00, 0x92.toByte()) + } + + /** + * 查询语音报警状态指令 + * */ + fun queryAlarmMode(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x01, 0x92.toByte(), 0x00, 0x00, 0x94.toByte()) + } + + /** + * 打开燃气报警指令 + */ + fun openMethaneAlarm(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x92.toByte(), 0x01, 0x00, 0x94.toByte()) + } + + /** + * 关闭燃气报警指令 + */ + fun closeMethaneAlarm(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x92.toByte(), 0x00, 0x00, 0x93.toByte()) + } + + /** + * 查询设备语音提示指令 + * */ + fun queryDeviceStateVoice(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x01, 0x97.toByte(), 0x00, 0x00, 0x99.toByte()) + } + + /** + * 打开设备语音提示指令 + */ + fun openVoiceTips(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x97.toByte(), 0x01, 0x00, 0x99.toByte()) + } + + /** + * 关闭设备语音提示指令 + */ + fun closeVoiceTips(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x97.toByte(), 0x00, 0x00, 0x98.toByte()) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/extensions/ByteArray.kt b/app/src/main/java/com/casic/br/operationsite/extensions/ByteArray.kt new file mode 100644 index 0000000..9fe5d16 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/extensions/ByteArray.kt @@ -0,0 +1,62 @@ +package com.casic.br.operationsite.extensions + +import kotlin.experimental.and + +/** + * ByteArray转Hex + * */ +fun ByteArray.toHex(): String { + val hexArray = "0123456789ABCDEF".toCharArray() + val hexChars = CharArray(this.size * 2) + for (j in this.indices) { + val i = this[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[i ushr 4] + hexChars[j * 2 + 1] = hexArray[i and 0x0F] + } + return String(hexChars) +} + +/** + * ByteArray转ASCII中文字符 + * */ +fun ByteArray.toAsciiCode(): String { + val builder = StringBuilder() + this.forEach { + builder.append(Char(it.toInt())) + } + return builder.toString() +} + +fun ByteArray.handleGasConcentration(): Int { + /** + * [1, 0, 0, 0, 13, 14] + * */ + //负值需要计算补码 + val x = if (this[1] < 0) { + this[1].toInt() and 0xFF + } else { + this[1].toInt() + } + val y = if (this[2] < 0) { + this[2].toInt() and 0xFF + } else { + this[2].toInt() + } + val z = if (this[3] < 0) { + this[3].toInt() and 0xFF + } else { + this[3].toInt() + } + return (x * 65536 + y * 256 + z) +} + +fun ByteArray.handleCpuTemperature(): Float { + //[1, -128, 24] + val x = this[0] and 0xFF.toByte() + val y = if (this[1] < 0) { + this[1].toInt() and 0xFF + } else { + this[1].toInt() + } + return (x * 256 + y) / 10f +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt index d3c20a7..0e2034f 100644 --- a/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt +++ b/app/src/main/java/com/casic/br/operationsite/service/SocketConnectionService.kt @@ -6,7 +6,15 @@ import android.os.IBinder import android.os.Message import android.util.Log +import com.casic.br.operationsite.extensions.handleCpuTemperature +import com.casic.br.operationsite.extensions.handleGasConcentration +import com.casic.br.operationsite.extensions.toHex +import com.casic.br.operationsite.fragments.BaseSettingsFragment +import com.casic.br.operationsite.fragments.MethaneMonitorFragment +import com.casic.br.operationsite.fragments.VoiceSettingsFragment +import com.casic.br.operationsite.utils.CommandCreator import com.casic.br.operationsite.utils.LocaleConstant +import com.pengxh.kt.lite.extensions.toAsciiCode import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.utils.socket.tcp.OnTcpConnectStateListener import com.pengxh.kt.lite.utils.socket.tcp.TcpClient @@ -22,11 +30,124 @@ override fun handleMessage(msg: Message): Boolean { when (msg.what) { + LocaleConstant.QUERY_METHANE_STATE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryMethaneState()) + } + LocaleConstant.OPEN_METHANE_CODE -> { + tcpClient.sendMessage(CommandCreator.openLaser()) + } + + LocaleConstant.CLOSE_METHANE_CODE -> { + tcpClient.sendMessage(CommandCreator.closeLaser()) + } + + LocaleConstant.QUERY_METHANE_THRESHOLD_CODE -> { + tcpClient.sendMessage(CommandCreator.queryMethaneThreshold()) + } + + LocaleConstant.UPDATE_GAS_THRESHOLD_CODE -> { + val threshold = msg.obj as Int + val thresholdCommand = CommandCreator.setThreshold(threshold) + tcpClient.sendMessage(thresholdCommand) + } + + LocaleConstant.QUERY_CPU_TEMPERATURE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryCpuTemperature()) + } + + LocaleConstant.QUERY_VOICE_VALUE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryVoiceValue()) + } + + LocaleConstant.INCREASE_VOICE_CODE -> { + tcpClient.sendMessage(CommandCreator.increaseVoice()) + } + + LocaleConstant.REDUCE_VOICE_CODE -> { + tcpClient.sendMessage(CommandCreator.reduceVoice()) + } + + LocaleConstant.QUERY_VOICE_MODE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryVoiceMode()) + } + + LocaleConstant.OPEN_LOCALE_MODE_CODE -> { + tcpClient.sendMessage(CommandCreator.openLocaleMode()) + } + + LocaleConstant.OPEN_REMOTE_MODE_CODE -> { + tcpClient.sendMessage(CommandCreator.openRemoteMode()) + } + + LocaleConstant.QUERY_ALARM_MODE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryAlarmMode()) + } + + LocaleConstant.OPEN_METHANE_ALARM_CODE -> { + tcpClient.sendMessage(CommandCreator.openMethaneAlarm()) + } + + LocaleConstant.CLOSE_METHANE_ALARM_CODE -> { + tcpClient.sendMessage(CommandCreator.closeMethaneAlarm()) + } + + LocaleConstant.QUERY_DEVICE_STATE_VOICE_CODE -> { + tcpClient.sendMessage(CommandCreator.queryDeviceStateVoice()) + } + + LocaleConstant.OPEN_DEVICE_STATE_TIPS_CODE -> { + tcpClient.sendMessage(CommandCreator.openVoiceTips()) + } + + LocaleConstant.CLOSE_DEVICE_STATE_TIPS_CODE -> { + tcpClient.sendMessage(CommandCreator.closeVoiceTips()) + } + + LocaleConstant.QUERY_BOARD_CONFIG_CODE -> { + tcpClient.sendMessage(CommandCreator.queryControlBoardConfig()) + } + + LocaleConstant.QUERY_WIFI_CONFIG_CODE -> { + tcpClient.sendMessage(CommandCreator.queryWiFiConfig()) + } + + LocaleConstant.QUERY_IS_USE_AI_CODE -> { + tcpClient.sendMessage(CommandCreator.queryIsUseAI()) + } + + LocaleConstant.QUERY_SERVER_CONFIG_CODE -> { + tcpClient.sendMessage(CommandCreator.queryServerConfig()) + } + + LocaleConstant.SET_BOARD_WIFI_CONFIG_CODE -> { + val params = msg.obj as Array<*> + tcpClient.sendMessage( + CommandCreator.setWiFiConfig(params[0].toString(), params[1].toString()) + ) + } + + LocaleConstant.SET_BOARD_SERVER_CONFIG_CODE -> { + val params = msg.obj as Array<*> + tcpClient.sendMessage( + CommandCreator.setServerConfig(params[0].toString(), params[1].toString()) + ) + } } return true } + /** + * 甲烷查询 + * */ + private val methaneRunnable = object : Runnable { + override fun run() { + tcpClient.sendMessage(CommandCreator.queryMethane()) + // 每3s重复一次 + weakReferenceHandler?.postDelayed(this, 3 * 1000L) + } + } + override fun onCreate() { super.onCreate() weakReferenceHandler = WeakReferenceHandler(this) @@ -36,14 +157,18 @@ override fun onConnected() { ForegroundRunningService.weakReferenceHandler?.sendEmptyMessage(2024110501) + //定时查询甲烷浓度 + weakReferenceHandler?.post(methaneRunnable) } override fun onDisconnected() { ForegroundRunningService.weakReferenceHandler?.sendEmptyMessage(2024110502) + weakReferenceHandler?.removeCallbacks(methaneRunnable) } override fun onConnectFailed() { ForegroundRunningService.weakReferenceHandler?.sendEmptyMessage(2024110503) + weakReferenceHandler?.removeCallbacks(methaneRunnable) } override fun onMessageReceived(bytes: ByteArray?) { @@ -51,10 +176,175 @@ return } Log.d(kTag, bytes.contentToString()) + //根据帧头判断。不能直接转为ascii,因为有的协议返回的不是ascii,会报错 + val dataHeadArray = bytes.copyOfRange(0, 7) + if (dataHeadArray.contentEquals(byteArrayOf(71, 101, 116, 68, 97, 116, 97))) { + //GetData + val dataArray = bytes.copyOfRange(10, bytes.size) + val data = dataArray.toAsciiCode().trim() + + val weakReferenceHandler = BaseSettingsFragment.weakReferenceHandler ?: return + + //判断类型 + when (Char(bytes[8].toInt())) { + '1' -> { + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.BOARD_CONFIG_RESPONSE_CODE + message.obj = data + weakReferenceHandler.sendMessage(message) + } + + '2' -> { + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.WIFI_CONFIG_RESPONSE_CODE + message.obj = data + weakReferenceHandler.sendMessage(message) + } + + '4' -> { + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_IS_USE_AI_RESPONSE_CODE + message.obj = data + weakReferenceHandler.sendMessage(message) + } + + '5' -> { + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.SERVER_CONFIG_RESPONSE_CODE + message.obj = data + weakReferenceHandler.sendMessage(message) + } + } + } else if (dataHeadArray.contentEquals(byteArrayOf(83, 101, 116, 68, 97, 116, 97))) { + //SetData + val dataArray = bytes.copyOfRange(10, bytes.size) + val data = dataArray.toAsciiCode().trim() + + val weakReferenceHandler = BaseSettingsFragment.weakReferenceHandler ?: return + + when (Char(bytes[8].toInt())) { + '2' -> { + if (data == "ok") { + weakReferenceHandler.sendEmptyMessage(LocaleConstant.SET_BOARD_WIFI_CONFIG_RESPONSE_CODE) + } + } + + '5' -> { + if (data == "ok") { + weakReferenceHandler.sendEmptyMessage(LocaleConstant.SET_BOARD_SERVER_CONFIG_RESPONSE_CODE) + } + } + } + } else if (bytes.size == 13) { + //取前6位解析设备编号 + val deviceCode = bytes.take(6).toByteArray().toHex() + if (BaseSettingsFragment.weakReferenceHandler != null) { + val weakReferenceHandler = BaseSettingsFragment.weakReferenceHandler!! + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.DEVICE_RESPONSE_CODE + message.obj = deviceCode + weakReferenceHandler.sendMessage(message) + } + + //取数据类型标志位,根据标志位解析不同的数据 + when ((bytes[6].toInt() and 0xFF).toString(16).uppercase()) { + "AA" -> { + //甲烷浓度 + val dataArray = bytes.copyOfRange(7, bytes.size) + val concentration = dataArray.handleGasConcentration() + val weakReferenceHandler = MethaneMonitorFragment.weakReferenceHandler ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_METHANE_RESPONSE_CODE + message.obj = concentration + weakReferenceHandler.sendMessage(message) + } + + "BB" -> { + when ((bytes[9].toInt() and 0xFF).toString(16).uppercase()) { + "90" -> { + //语音源模式 + val weakReferenceHandler = VoiceSettingsFragment.weakReferenceHandler + ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_VOICE_MODE_RESPONSE_CODE + message.obj = bytes[10].toInt() + weakReferenceHandler.sendMessage(message) + } + + "91" -> { + //激光状态 + val weakReferenceHandler = MethaneMonitorFragment.weakReferenceHandler + ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_METHANE_STATE_RESPONSE_CODE + message.obj = bytes[10].toInt() + weakReferenceHandler.sendMessage(message) + } + + "92" -> { + //燃气报警开关 + val weakReferenceHandler = VoiceSettingsFragment.weakReferenceHandler + ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_ALARM_MODE_RESPONSE_CODE + message.obj = bytes[10].toInt() + weakReferenceHandler.sendMessage(message) + } + + "97" -> { + //设备状态语音提示开关 + val weakReferenceHandler = VoiceSettingsFragment.weakReferenceHandler + ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_DEVICE_STATE_VOICE_RESPONSE_CODE + message.obj = bytes[10].toInt() + weakReferenceHandler.sendMessage(message) + } + + "98" -> { + //音量调节 + if (bytes[8].toInt() == 1) { + val weakReferenceHandler = + VoiceSettingsFragment.weakReferenceHandler ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_VOICE_VALUE_RESPONSE_CODE + message.obj = bytes[10].toInt() + weakReferenceHandler.sendMessage(message) + } else { + Log.d(kTag, "onMessageReceived: 调节音量返回值不处理") + } + } + } + } + + "CC" -> { + //激光温度 + val dataArray = bytes.copyOfRange(10, bytes.size) + val weakReferenceHandler = MethaneMonitorFragment.weakReferenceHandler ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_CPU_TEMPERATURE_RESPONSE_CODE + message.obj = dataArray.handleCpuTemperature() + weakReferenceHandler.sendMessage(message) + } + } + } else if (bytes.size == 14) { + if ((bytes[6].toInt() and 0xFF).toString(16).uppercase() == "BB") { + if ((bytes[9].toInt() and 0xFF).toString(16).uppercase() == "94") { + val dataArray = bytes.copyOfRange(9, bytes.size) + val concentration = dataArray.handleGasConcentration() + val weakReferenceHandler = MethaneMonitorFragment.weakReferenceHandler ?: return + val message = weakReferenceHandler.obtainMessage() + message.what = LocaleConstant.QUERY_METHANE_THRESHOLD_RESPONSE_CODE + message.obj = concentration + weakReferenceHandler.sendMessage(message) + } + } + } } override fun onDestroy() { super.onDestroy() + weakReferenceHandler?.removeCallbacks(methaneRunnable) tcpClient.stop(false) Log.d(kTag, "onDestroy: SocketConnectionService") } diff --git a/app/src/main/java/com/casic/br/operationsite/utils/CommandCreator.kt b/app/src/main/java/com/casic/br/operationsite/utils/CommandCreator.kt new file mode 100644 index 0000000..aadb0b7 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/utils/CommandCreator.kt @@ -0,0 +1,217 @@ +package com.casic.br.operationsite.utils + +object CommandCreator { + /** + * 查询激光状态 + * */ + fun queryMethaneState(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x01, 0x91.toByte(), 0x00, 0x00, 0x93.toByte()) + } + + /** + * 打开激光指令 + */ + fun openLaser(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x01, 0x00, 0x93.toByte()) + } + + /** + * 关闭激光指令 + */ + fun closeLaser(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x00, 0x00, 0x92.toByte()) + } + + /** + * 查询甲烷浓度指令 + */ + fun queryMethane(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x95.toByte(), 0x00, 0x00, 0x96.toByte()) + } + + /** + * 查询甲烷阈值指令 + * */ + fun queryMethaneThreshold(): ByteArray { + return byteArrayOf( + 0xAA.toByte(), + 0x01, + 0x01, + 0x94.toByte(), + 0x00, + 0x00, + 0x00, + 0x96.toByte() + ) + } + + /** + * 设置甲烷阈值指令 + */ + fun setThreshold(threshold: Int): ByteArray { + //数据位和校验位先都设置0x00占位 + val bytes = byteArrayOf( + 0xAA.toByte(), + 0x01, + 0x00, + 0x94.toByte(), + 0x00.toByte(), + 0x00.toByte(), + 0x00.toByte(), + 0x00.toByte() + ) + for (i in 0..255) { + for (j in 0..255) { + for (k in 0..255) { + //浓度值 = 数据码1 * 65536 + 数据码2 * 256 + 数据码3 + if (65536 * i + 256 * j + k == threshold) { + bytes[4] = i.toByte() + bytes[5] = j.toByte() + bytes[6] = k.toByte() + + //计算校验位。 + var sum = 0 + for (l in 1 until bytes.size - 1) { + sum += bytes[l] + } + bytes[7] = sum.toByte() + } + } + } + } + return bytes + } + + /** + * 查询甲烷芯片温度指令 + * */ + fun queryCpuTemperature(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x96.toByte(), 0x00, 0x00, 0x97.toByte()) + } + + /** + * 查询主控板主控板IP、子网掩码、网关IP指令 + * */ + fun queryControlBoardConfig(): ByteArray { + return "GetData:1\r\n".toByteArray() + } + + /** + * 查询是否和一体机一起使用指令 + * */ + fun queryIsUseAI(): ByteArray { + return "GetData:4\r\n".toByteArray() + } + + /** + * 安全树主控板要连接的远程服务器IP、端口号指令 + * */ + fun queryServerConfig(): ByteArray { + return "GetData:5\r\n".toByteArray() + } + + /** + * 设置主控板WiFi配置指令 + * */ + fun setWiFiConfig(wifiName: String, password: String): ByteArray { + return "SetData:2,${wifiName},${password}\r\n".toByteArray() + } + + /** + * 查询主控板WiFi配置指令 + * */ + fun queryWiFiConfig(): ByteArray { + return "GetData:2\r\n".toByteArray() + } + + /** + * 设置主控板服务地址指令 + * */ + fun setServerConfig(host: String, port: String): ByteArray { + return "SetData:5,${host},${port}\r\n".toByteArray() + } + + /** + * 查询音量值 + * */ + fun queryVoiceValue(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x01, 0x98.toByte(), 0x00, 0x00, 0x9A.toByte()) + } + + /** + * 音量增大指令 + * */ + fun increaseVoice(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x98.toByte(), 0x01, 0x00, 0x9A.toByte()) + } + + /** + * 音量减小指令 + * */ + fun reduceVoice(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x98.toByte(), 0x00, 0x00, 0x99.toByte()) + } + + /** + * 查询语音模式指令 + * */ + fun queryVoiceMode(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x01, 0x90.toByte(), 0x00, 0x00, 0x92.toByte()) + } + + /** + * 切换本地音源指令 + * */ + fun openLocaleMode(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x90.toByte(), 0x00, 0x00, 0x91.toByte()) + } + + /** + * 切换远程音源指令 + * */ + fun openRemoteMode(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x90.toByte(), 0x01, 0x00, 0x92.toByte()) + } + + /** + * 查询语音报警状态指令 + * */ + fun queryAlarmMode(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x01, 0x92.toByte(), 0x00, 0x00, 0x94.toByte()) + } + + /** + * 打开燃气报警指令 + */ + fun openMethaneAlarm(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x92.toByte(), 0x01, 0x00, 0x94.toByte()) + } + + /** + * 关闭燃气报警指令 + */ + fun closeMethaneAlarm(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x92.toByte(), 0x00, 0x00, 0x93.toByte()) + } + + /** + * 查询设备语音提示指令 + * */ + fun queryDeviceStateVoice(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x01, 0x97.toByte(), 0x00, 0x00, 0x99.toByte()) + } + + /** + * 打开设备语音提示指令 + */ + fun openVoiceTips(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x97.toByte(), 0x01, 0x00, 0x99.toByte()) + } + + /** + * 关闭设备语音提示指令 + */ + fun closeVoiceTips(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x97.toByte(), 0x00, 0x00, 0x98.toByte()) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index 261d21a..cd63565 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -49,7 +49,7 @@ const val SERVER_BASE_URL = "http://111.198.10.15:22006" //一体机DeviceMonitor程序TCP Server IP地址 - const val GAS_BASE_IP = "192.168.10.139" + const val GAS_BASE_IP = "192.168.10.51" const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" const val DEVICE_CONTROL_SERVER_CONFIG = "deviceControlServerConfig" @@ -65,7 +65,7 @@ val GENDER = arrayListOf("男", "女") - const val TCP_PORT = 9000 + const val TCP_PORT = 333 const val TCP_CONNECTED_CODE = 103 const val TCP_DISCONNECTED_CODE = 104