package com.shlb.comb.activity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.text.Html;
import android.widget.Toast;
import com.shlb.comb.R;
import com.shlb.comb.base.BaseActivity;
import com.shlb.comb.event.UpdateEvent;
import com.shlb.comb.manager.BleGlobalManager;
import com.shlb.comb.util.CMD;
import com.shlb.comb.util.CRCutil;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class AdvancedSettingActivity extends BaseActivity {
private EditText et_mainboard_version;
private Button btn_mainboard_read;
private EditText et_display_version;
private Button btn_display_read;
private Button btn_start_addressing;
private Button btn_end_addressing;
private Button btn_clear_log;
private TextView tv_log;
private TextView tv_right_text;
private TextView tv_mainboard_status;
private TextView tv_sensor_status;
private StringBuilder logBuilder = new StringBuilder();
private String currentExecutingCmd = "";
private View currentOperatingButton;
@Override
protected void contentView() {
setContentView(R.layout.activity_advanced_setting);
}
@Override
protected void initView() {
super.initHead();
if (tv_center != null) {
tv_center.setText("高级设置");
}
if (iv_left != null) {
iv_left.setImageResource(R.mipmap.icon_back);
}
et_mainboard_version = findViewById(R.id.et_mainboard_version);
btn_mainboard_read = findViewById(R.id.btn_mainboard_read);
et_display_version = findViewById(R.id.et_display_version);
btn_display_read = findViewById(R.id.btn_display_read);
btn_start_addressing = findViewById(R.id.btn_start_addressing);
btn_end_addressing = findViewById(R.id.btn_end_addressing);
btn_clear_log = findViewById(R.id.btn_clear_log);
tv_log = findViewById(R.id.tv_log);
tv_right_text = findViewById(R.id.tv_right_text);
tv_mainboard_status = findViewById(R.id.tv_mainboard_status);
tv_sensor_status = findViewById(R.id.tv_sensor_status);
// Initialize log
logBuilder.append("日志记录:
");
tv_log.setText(Html.fromHtml(logBuilder.toString()));
}
@Override
protected void initData() {
updateBluetoothStatus();
if (BleGlobalManager.getInstance().isConnected()) {
sendCmdWithCrc(CMD.ENTER_SETTING);
triggerAutoRead();
}
}
@Override
protected void onDestroy() {
if (BleGlobalManager.getInstance().isConnected()) {
sendCmdWithCrc(CMD.EXIT_SETTING);
}
super.onDestroy();
}
@Override
protected void initEvent() {
View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View v) {
int id = v.getId();
String action = "";
if (id == R.id.btn_mainboard_read) {
currentOperatingButton = btn_mainboard_read;
updateButtonState(currentOperatingButton, false);
action = "读取主板版本";
currentExecutingCmd = CMD.READ_BOARD_VERSION;
sendCmdWithCrc(CMD.READ_BOARD_VERSION);
} else if (id == R.id.btn_display_read) {
currentOperatingButton = btn_display_read;
updateButtonState(currentOperatingButton, false);
action = "读取传感器版本";
currentExecutingCmd = CMD.READ_SENSOR_VERSION;
sendCmdWithCrc(CMD.READ_SENSOR_VERSION);
} else if (id == R.id.btn_start_addressing) {
currentOperatingButton = btn_start_addressing;
updateButtonState(currentOperatingButton, false);
action = "开始编址";
currentExecutingCmd = CMD.WRITE_START_ADDRESS;
sendCmdWithCrc(CMD.WRITE_START_ADDRESS);
} else if (id == R.id.btn_end_addressing) {
currentOperatingButton = btn_end_addressing;
updateButtonState(currentOperatingButton, false);
action = "结束编址";
currentExecutingCmd = CMD.WRITE_END_ADDRESS;
sendCmdWithCrc(CMD.WRITE_END_ADDRESS);
} else if (id == R.id.btn_clear_log) {
logBuilder.setLength(0);
logBuilder.append("日志记录:
");
tv_log.setText(Html.fromHtml(logBuilder.toString()));
}
if (!action.isEmpty() && id != R.id.btn_start_addressing && id != R.id.btn_end_addressing) {
// Toast.makeText(AdvancedSettingActivity.this, action, Toast.LENGTH_SHORT).show();
// addLog(action);
}
}
};
btn_mainboard_read.setOnClickListener(listener);
btn_display_read.setOnClickListener(listener);
btn_start_addressing.setOnClickListener(listener);
btn_end_addressing.setOnClickListener(listener);
btn_clear_log.setOnClickListener(listener);
}
private void addLog(String message) {
appendLog(message, null);
}
private String getCmdDescription(String hex) {
if (hex == null) return "";
// 发送指令匹配
if (hex.startsWith(CMD.ENTER_SETTING)) return "-进入设定";
if (hex.startsWith(CMD.EXIT_SETTING)) return "-退出设定";
if (hex.startsWith(CMD.READ_BOARD_VERSION)) return "-读取主板版本";
if (hex.startsWith(CMD.READ_SENSOR_VERSION)) return "-读取传感器版本";
if (hex.startsWith(CMD.WRITE_START_ADDRESS)) return "-开始编址";
if (hex.startsWith(CMD.WRITE_END_ADDRESS)) return "-结束编址";
// 接收数据匹配
// 读取主板版本返回 (A55A03 0A ...)
if (hex.startsWith("A55A030A")) return "-读取主板版本";
// 读取传感器版本返回 (A55A03 0B ...)
if (hex.startsWith("A55A030B")) return "-读取传感器版本";
// 写入返回 (A55A06开头)
if (hex.startsWith("A55A06") && hex.length() >= 12) {
return "-写入返回";
}
return "";
}
private void appendLog(String msg, Boolean isSent) {
String time = com.blankj.utilcode.util.TimeUtils.getNowString(new java.text.SimpleDateFormat("HH:mm:ss.SSS"));
String displayMsg = msg;
String cmdDesc = "";
// 如果是 hex 指令 (纯 0-9 A-F a-f),加空格格式化
if (msg.matches("^[0-9A-Fa-f]+$")) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < msg.length(); i += 2) {
if (i + 2 <= msg.length()) {
sb.append(msg.substring(i, i + 2)).append(" ");
} else {
sb.append(msg.substring(i));
}
}
displayMsg = sb.toString().trim();
// 获取指令描述
cmdDesc = getCmdDescription(msg);
}
String logLine;
if (isSent != null) {
String color = isSent ? "#1890ff" : "#05aa87"; // Blue for sent, Green for received
// 拼接到前缀后面: "发送-读站号: " 或 "收到-读站号: "
String prefix = (isSent ? "发送" : "收到") + cmdDesc + ": ";
logLine = time + " " + prefix + displayMsg + "
";
} else {
// System/Local log (Black)
logLine = time + " " + displayMsg + "
";
}
logBuilder.append(logLine);
if (tv_log != null) {
tv_log.setText(Html.fromHtml(logBuilder.toString()));
}
}
private void updateBluetoothStatus() {
if (tv_right_text == null) return;
if (BleGlobalManager.getInstance().isConnected()) {
String name = "未知设备";
if (BleGlobalManager.getInstance().getBluetoothLeDevice() != null) {
String deviceName = BleGlobalManager.getInstance().getBluetoothLeDevice().getName();
if (deviceName != null && !deviceName.isEmpty()) {
name = deviceName;
}
}
tv_right_text.setText(name);
} else {
tv_right_text.setText("未连接");
}
}
private void triggerAutoRead() {
showLoading("正在同步版本信息...");
// Reset status
setLabelStatus(tv_mainboard_status, "", R.color.base_text);
setLabelStatus(tv_sensor_status, "", R.color.base_text);
// Read Mainboard
new android.os.Handler().postDelayed(() -> {
if (btn_mainboard_read != null) btn_mainboard_read.performClick();
}, 200);
// Read Sensor
new android.os.Handler().postDelayed(() -> {
if (btn_display_read != null) btn_display_read.performClick();
}, 1200);
// Hide loading
new android.os.Handler().postDelayed(() -> hiddeLoading(), 2500);
}
private void setLabelStatus(TextView view, String text, int colorResId) {
if (view != null) {
view.setText(text);
view.setTextColor(getResources().getColor(colorResId));
}
}
private void sendCmdWithCrc(String cmd) {
if (!BleGlobalManager.getInstance().isConnected()) {
Toast.makeText(this, "请先连接蓝牙", Toast.LENGTH_SHORT).show();
addLog("错误: 蓝牙未连接");
return;
}
byte[] cmdBytes = BleGlobalManager.hexStringToBytes(cmd);
if (cmdBytes != null) {
String crc = CRCutil.getCRC(cmdBytes);
// Pad CRC to 4 chars if needed
while (crc.length() < 4) {
crc = "0" + crc;
}
String fullCmd = cmd + crc.toUpperCase();
appendLog(fullCmd, true); // true for sent (Blue)
BleGlobalManager.getInstance().sendCmd(fullCmd);
} else {
addLog("错误: 指令转换失败");
}
}
private void updateButtonState(View btn, boolean enable) {
if (btn == null) return;
btn.setEnabled(enable);
if (enable) {
btn.getBackground().clearColorFilter();
} else {
btn.getBackground().setColorFilter(android.graphics.Color.GRAY, android.graphics.PorterDuff.Mode.MULTIPLY);
}
}
private void restoreCurrentButton() {
if (currentOperatingButton != null) {
updateButtonState(currentOperatingButton, true);
currentOperatingButton = null;
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(UpdateEvent event) {
if (event.getType() == UpdateEvent.Type.CONN_STATU) {
updateBluetoothStatus();
if (event.getObj() instanceof Integer && (int) event.getObj() == android.bluetooth.BluetoothProfile.STATE_CONNECTED) {
triggerAutoRead();
}
} else if (event.getType() == UpdateEvent.Type.DEVICE_INFO) {
String hex = event.getMsg();
appendLog(hex, false); // false for received (Green)
parseAndRefresh(hex);
}
}
private void parseAndRefresh(String hex) {
if (hex == null) return;
// 写入指令的返回 (A55A06开头)
if (hex.startsWith("A55A06") && hex.length() >= 12) {
restoreCurrentButton();
parseWriteResponse(hex);
return;
}
// 读取指令的返回 (A55A03开头)
if (hex.startsWith("A55A03") && hex.length() >= 8) {
restoreCurrentButton();
parseReadResponse(hex);
}
}
private void parseReadResponse(String hex) {
try {
// 命令类型: 第7-8位 (Index 6-8)
String cmdType = hex.substring(6, 8);
// 数据部分通常从第11-12位开始 (Index 10)
// 假设版本号数据就在后面
String dataHex = "";
if (hex.length() > 10) {
// 去掉CRC (最后4位)? 不确定长度,先取所有
// 暂时取 substring(10) 直到 length-4 (如果带CRC)
// 简单起见,取 substring(10)
dataHex = hex.substring(10);
// 如果最后4位是CRC,可能需要去掉。通常 CRC 是最后4字符。
if (dataHex.length() > 4) {
dataHex = dataHex.substring(0, dataHex.length() - 4);
}
}
if ("0A".equals(cmdType)) {
// 主板版本
String version = formatVersionHex(dataHex);
if (et_mainboard_version != null) et_mainboard_version.setText(version);
setLabelStatus(tv_mainboard_status, "(读取值)", R.color.base_color);
addLog("读取主板版本成功: " + version);
} else if ("0B".equals(cmdType)) {
// 传感器版本
String version = formatVersionHex(dataHex);
if (et_display_version != null) et_display_version.setText(version);
setLabelStatus(tv_sensor_status, "(读取值)", R.color.base_color);
addLog("读取传感器版本成功: " + version);
}
} catch (Exception e) {
e.printStackTrace();
addLog("解析读取返回异常: " + e.getMessage());
}
}
private String formatVersionHex(String hex) {
if (hex == null || hex.isEmpty()) return "";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hex.length(); i++) {
sb.append(hex.charAt(i));
if (i % 2 == 1 && i < hex.length() - 1) {
sb.append("-");
}
}
return sb.toString();
}
private void parseWriteResponse(String hex) {
try {
// 写入指令的返回 (A55A06开头)
if (hex.startsWith("A55A06") && hex.length() >= 12) {
// 结果状态: 第11-12位 (Index 10-12)
String statusHex = hex.substring(10, 12);
boolean isSuccess = "01".equals(statusHex);
if (!currentExecutingCmd.isEmpty()) {
if (isSuccess) {
if (currentExecutingCmd.startsWith(CMD.WRITE_START_ADDRESS)) {
addLog("开始编址成功");
Toast.makeText(this, "开始编址成功", Toast.LENGTH_SHORT).show();
} else if (currentExecutingCmd.startsWith(CMD.WRITE_END_ADDRESS)) {
addLog("结束编址成功");
Toast.makeText(this, "结束编址成功", Toast.LENGTH_SHORT).show();
}
} else {
addLog("操作失败: " + hex);
Toast.makeText(this, "操作失败", Toast.LENGTH_SHORT).show();
}
// Reset current command after handling
currentExecutingCmd = "";
}
}
} catch (Exception e) {
e.printStackTrace();
addLog("解析异常: " + e.getMessage());
}
}
}