去掉仪表盘风格
url 设置修改 串口命令发送3次,避免发送失败
This commit is contained in:
@@ -37,7 +37,6 @@ import cn.ykbox.dashboard.ConfigReader;
|
||||
import cn.ykbox.dashboard.databinding.ActivityBuildingDashboardBinding;
|
||||
import cn.ykbox.dashboard.perferences.PreferenceConfiguration;
|
||||
import cn.ykbox.dashboard.receiver.CommandBroadcastReceiver;
|
||||
import cn.ykbox.dashboard.serial.SerialControlDevices;
|
||||
import cn.ykbox.dashboard.serial.SerialPortDetector;
|
||||
|
||||
public class BuildingDashboardActivity extends FullscreenActivity {
|
||||
@@ -104,8 +103,11 @@ public class BuildingDashboardActivity extends FullscreenActivity {
|
||||
super.onResume();
|
||||
|
||||
SharedPreferences pre = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
mainUrl = pre.getString("k_url_prefix", "http://172.18.22.211:8002/Dashboard");
|
||||
configUrl = mainUrl + "/data/config.json";
|
||||
String urlPrefix = pre.getString("k_url_prefix", "http://172.18.22.211:8002/Dashboard");
|
||||
String urlPath = pre.getString("k_url_path", "/index.html");
|
||||
|
||||
mainUrl = urlPrefix + urlPath;
|
||||
configUrl = urlPrefix + "/data/config.json";
|
||||
|
||||
Log.i(TAG, "Main: " + mainUrl);
|
||||
Log.i(TAG, "Config: " + configUrl);
|
||||
@@ -137,11 +139,12 @@ public class BuildingDashboardActivity extends FullscreenActivity {
|
||||
new Thread(() -> {
|
||||
detector.sendPowerOffCommand();
|
||||
try {
|
||||
Thread.sleep(3000); // 等待 3 秒
|
||||
Thread.sleep(5000); // 等待 5 秒
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, "Sleep interrupted", e);
|
||||
}
|
||||
detector.sendPowerOnCommand();
|
||||
int loop = PreferenceConfiguration.getSerialCmdLoop(this);
|
||||
detector.sendPowerOnCommand(loop);
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
@@ -176,7 +179,7 @@ public class BuildingDashboardActivity extends FullscreenActivity {
|
||||
Log.d(TAG, "Testing port " + current + "/" + total + ": " + portPath);
|
||||
runOnUiThread(() -> {
|
||||
if (progressDialog != null) {
|
||||
progressDialog.setMessage("正在测试串口 " + current + "/" + total + "\n" + portPath);
|
||||
progressDialog.setMessage("正在测试串口路径: " + portPath + "\n" + current + "/" + total);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
package cn.ykbox.dashboard.activity;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.preference.EditTextPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
|
||||
@@ -80,7 +79,15 @@ public class SettingsActivity extends AppCompatActivity {
|
||||
.setTitle("确认清除")
|
||||
.setMessage("确定要清除当前串口设备路径吗?")
|
||||
.setPositiveButton("确定", (dialog, which) -> {
|
||||
// 清空
|
||||
PreferenceConfiguration.setSerialPortPath(requireContext(), "");
|
||||
|
||||
// 刷新
|
||||
Preference serialPortPathPref = findPreference("k_serial_port_path");
|
||||
if (serialPortPathPref != null) {
|
||||
String newValue = PreferenceConfiguration.getSerialPortPath(requireContext());
|
||||
((EditTextPreference) serialPortPathPref).setText(newValue);
|
||||
}
|
||||
})
|
||||
.setNegativeButton("取消", null)
|
||||
.show();
|
||||
@@ -96,7 +103,7 @@ public class SettingsActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
SerialPortDetector detector = new SerialPortDetector(portPath, baudRate);
|
||||
detector.sendPowerOnCommand();
|
||||
detector.sendPowerOnCommand(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
|
||||
import cn.ykbox.dashboard.R;
|
||||
import cn.ykbox.dashboard.serial.SerialControlDevices;
|
||||
|
||||
public class StartActivity extends AppCompatActivity {
|
||||
private Context mContext;
|
||||
|
||||
@@ -33,6 +33,10 @@ public class PreferenceConfiguration {
|
||||
|
||||
public static boolean getSendPowerOnCmd(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
return prefs.getBoolean(KEY_SEND_POWER_ON_CMD, false);
|
||||
return prefs.getBoolean(KEY_SEND_POWER_ON_CMD, true);
|
||||
}
|
||||
|
||||
public static int getSerialCmdLoop(Context context) {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,11 @@ package cn.ykbox.dashboard.receiver;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import cn.ykbox.dashboard.perferences.PreferenceConfiguration;
|
||||
import cn.ykbox.dashboard.serial.SerialControlDevices;
|
||||
import cn.ykbox.dashboard.serial.SerialPortDetector;
|
||||
|
||||
public class CommandBroadcastReceiver extends BroadcastReceiver {
|
||||
private static final String TAG = "CommandReceiver";
|
||||
@@ -24,11 +21,12 @@ public class CommandBroadcastReceiver extends BroadcastReceiver {
|
||||
|
||||
String portPath = PreferenceConfiguration.getSerialPortPath(context);
|
||||
int baudRate = PreferenceConfiguration.getSerialPortBaudRate(context);
|
||||
int loop = PreferenceConfiguration.getSerialCmdLoop(context);
|
||||
|
||||
if (hexCommand != null && !hexCommand.isEmpty() && !TextUtils.isEmpty(portPath)) {
|
||||
Log.d(TAG, "Received alarm to send command '" + hexCommand + "' to port '" + portPath + "' at " + baudRate + " baud");
|
||||
// 使用新的静态方法发送指令
|
||||
boolean success = SerialControlDevices.sendCommand(portPath, baudRate, hexCommand);
|
||||
boolean success = SerialPortDetector.sendCommand(portPath, baudRate, hexCommand, loop);
|
||||
if (!success) {
|
||||
Log.e(TAG, "Failed to send command via broadcast receiver.");
|
||||
}
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
package cn.ykbox.dashboard.serial;
|
||||
|
||||
import android.util.Log;
|
||||
import tp.xmaihh.serialport.SerialHelper;
|
||||
|
||||
/**
|
||||
* @description: 通过串口设置班牌的功能。本类提供一个静态方法用于发送单次命令。
|
||||
* @author: Hu Zhang <hu.zhang@live.com>
|
||||
* @date: 2024/1/5
|
||||
**/
|
||||
public class SerialControlDevices {
|
||||
private static final String TAG = "SerialControlDevices";
|
||||
|
||||
/**
|
||||
* 私有构造函数,防止外部实例化此类。
|
||||
*/
|
||||
private SerialControlDevices() {}
|
||||
|
||||
/**
|
||||
* 打开指定串口,发送十六进制命令,然后立即关闭串口。
|
||||
*
|
||||
* @param portPath 串口的设备路径 (例如, "/dev/ttyS2").
|
||||
* @param hexCommand 要发送的十六进制格式的命令字符串.
|
||||
* @return 如果命令发送成功则返回 true, 否则返回 false.
|
||||
*/
|
||||
public static boolean sendCommand(String portPath, int baud, String hexCommand) {
|
||||
if (portPath == null || portPath.isEmpty() || hexCommand == null || hexCommand.isEmpty()) {
|
||||
Log.e(TAG, "Port path or command is empty.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 每次调用都创建一个新的 SerialHelper 实例
|
||||
SerialHelper serialHelper = new SerialHelper(portPath, baud) {
|
||||
@Override
|
||||
protected void onDataReceived(tp.xmaihh.serialport.bean.ComBean ComRecData) {
|
||||
// 可以在这里处理返回的数据,但对于单次发送任务,通常不需要
|
||||
// Log.d(TAG, "Received data from " + portPath + ": " + new String(ComRecData.bRec));
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
serialHelper.open();
|
||||
serialHelper.sendHex(hexCommand);
|
||||
Log.d(TAG, "Successfully sent command '" + hexCommand + "' to port '" + portPath + "'");
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error sending command to port " + portPath, e);
|
||||
return false;
|
||||
} finally {
|
||||
serialHelper.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ public class SerialPortDetector {
|
||||
private static final String TEST_CMD_ON = "ACEAB400ED"; // 打开设备
|
||||
|
||||
// 响应超时时间(毫秒)
|
||||
private static final long RESPONSE_TIMEOUT = 6000;
|
||||
private static final long RESPONSE_TIMEOUT = 4000;
|
||||
|
||||
private DetectionCallback callback;
|
||||
private Handler mainHandler;
|
||||
@@ -35,6 +35,44 @@ public class SerialPortDetector {
|
||||
void onDetectionFailed();
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开指定串口,发送十六进制命令,然后立即关闭串口。
|
||||
*
|
||||
* @param portPath 串口的设备路径 (例如, "/dev/ttyS2").
|
||||
* @param hexCommand 要发送的十六进制格式的命令字符串.
|
||||
* @return 如果命令发送成功则返回 true, 否则返回 false.
|
||||
*/
|
||||
public static boolean sendCommand(String portPath, int baud, String hexCommand, int loop) {
|
||||
if (portPath == null || portPath.isEmpty() || hexCommand == null || hexCommand.isEmpty()) {
|
||||
Log.e(TAG, "Port path or command is empty.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 每次调用都创建一个新的 SerialHelper 实例
|
||||
SerialHelper serialHelper = new SerialHelper(portPath, baud) {
|
||||
@Override
|
||||
protected void onDataReceived(tp.xmaihh.serialport.bean.ComBean ComRecData) {
|
||||
// 可以在这里处理返回的数据,但对于单次发送任务,通常不需要
|
||||
// Log.d(TAG, "Received data from " + portPath + ": " + new String(ComRecData.bRec));
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
serialHelper.open();
|
||||
for(int i = 0; i < loop; i ++) {
|
||||
serialHelper.sendHex(hexCommand);
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
Log.d(TAG, "Successfully sent command '" + hexCommand + "' to port '" + portPath + "'");
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error sending command to port " + portPath, e);
|
||||
return false;
|
||||
} finally {
|
||||
serialHelper.close();
|
||||
}
|
||||
}
|
||||
|
||||
public SerialPortDetector(String savedPath, int baudRate) {
|
||||
this.savedPath = savedPath;
|
||||
this.baudRate = baudRate;
|
||||
@@ -55,15 +93,18 @@ public class SerialPortDetector {
|
||||
/**
|
||||
* 发送打开设备指令到已保存的串口(不等待响应)
|
||||
*/
|
||||
public void sendPowerOnCommand() {
|
||||
sendCommand(TEST_CMD_ON);
|
||||
public void sendPowerOnCommand(int loop) {
|
||||
sendCommand(TEST_CMD_ON, loop);
|
||||
}
|
||||
private void sendCommand(String commandHex) {
|
||||
sendCommand(commandHex, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送指令到已保存的串口(不等待响应)
|
||||
* @param commandHex 十六进制命令字符串
|
||||
*/
|
||||
private void sendCommand(String commandHex) {
|
||||
private void sendCommand(String commandHex, int loop) {
|
||||
if (TextUtils.isEmpty(savedPath)) {
|
||||
Log.w(TAG, "No serial port path configured");
|
||||
return;
|
||||
@@ -74,7 +115,12 @@ public class SerialPortDetector {
|
||||
try {
|
||||
serialHelper = new SimpleSerialHelper(savedPath, baudRate);
|
||||
serialHelper.open();
|
||||
|
||||
for(int i = 0; i < loop; i ++) {
|
||||
serialHelper.sendHex(commandHex);
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
Log.d(TAG, "Sent command: " + commandHex);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error sending command: " + e.getMessage());
|
||||
@@ -146,6 +192,13 @@ public class SerialPortDetector {
|
||||
|
||||
Log.d(TAG, "Testing port: " + portPath + " at " + baudRate + " baud");
|
||||
|
||||
// 老设备没有反馈,如果测试成功,很快就进入下个测试,导致用户看不清串口路径,这里添加延时
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, "Sleep interrupted", e);
|
||||
}
|
||||
|
||||
if (testSerialPort(portPath, baudRate, ensurePowerOn)) {
|
||||
Log.i(TAG, "Serial port detected successfully: " + portPath);
|
||||
notifyDetectionSuccess(portPath);
|
||||
@@ -172,6 +225,7 @@ public class SerialPortDetector {
|
||||
|
||||
if (ensurePowerOn) {
|
||||
// 需要确保设备开机,两个命令都要发送
|
||||
//
|
||||
Log.d(TAG, "Ensuring device power on by sending both commands");
|
||||
|
||||
boolean cmd1Success = sendCommandAndWaitResponse(serialHelper, TEST_CMD_OFF);
|
||||
@@ -326,24 +380,22 @@ public class SerialPortDetector {
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查响应是否符合格式: DA XX XX XX XX ED
|
||||
* 检查响应是否符合格式: DA XX XX XX XX ED 或者 AC XX XX XX XX ED
|
||||
*/
|
||||
private boolean isValidResponse(byte[] data) {
|
||||
if (data == null || data.length < 6) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查起始字节是否为 0xDA
|
||||
if ((data[0] & 0xFF) != 0xDA) {
|
||||
// 检查起始字节是否为 0xDA 或 0xAC
|
||||
int head = data[0] & 0xFF;
|
||||
if (head != 0xDA && head != 0xAC) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查结束字节是否为 0xED
|
||||
if ((data[data.length - 1] & 0xFF) != 0xED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
int end = data[data.length - 1] & 0xFF;
|
||||
return end == 0xED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,31 +1,37 @@
|
||||
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<PreferenceCategory app:title="网页地址">
|
||||
<PreferenceCategory app:title="服务器端地址">
|
||||
<EditTextPreference
|
||||
app:key="k_url_prefix"
|
||||
app:title="URL 前缀"
|
||||
app:defaultValue="http://172.18.22.211:8002/Dashboard"
|
||||
app:summary="用于拼接网页和配置文件链接,网页:{URL前缀}/{URL路径},配置文件:{URL前缀}/data/config.json" />
|
||||
<EditTextPreference
|
||||
app:key="k_url_path"
|
||||
app:title="URL 路径"
|
||||
app:defaultValue="/index.html"
|
||||
app:useSimpleSummaryProvider="true"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory app:title="配置物联网关">
|
||||
<EditTextPreference
|
||||
app:key="k_serial_port_path"
|
||||
app:title="串口设备"
|
||||
app:title="串口设备路径"
|
||||
app:defaultValue=""
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
<EditTextPreference
|
||||
app:key="k_serial_baud"
|
||||
app:title="串口波特率"
|
||||
app:defaultValue="9600"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
app:useSimpleSummaryProvider="true"
|
||||
app:isPreferenceVisible="false"/>
|
||||
<CheckBoxPreference
|
||||
app:key="k_send_power_on_cmd"
|
||||
app:title="App 启动时发送打开电源指令"
|
||||
app:summary="每次启动 App 时先发送关闭电源指令,再发送打开电源指令"
|
||||
app:defaultValue="false" />
|
||||
app:title="APP 启动时重启电源插座"
|
||||
app:summary="APP 启动时先关闭电源,5秒后再打开电源"
|
||||
app:defaultValue="true" />
|
||||
<Preference
|
||||
app:key="k_clear_device"
|
||||
app:title="清除设备"
|
||||
app:title="串口设备路径"
|
||||
app:summary="清除当前串口设备路径, 下次启动时自动检测设备。" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory app:title="测试物联网关">
|
||||
|
||||
Reference in New Issue
Block a user