431 lines
17 KiB
C
431 lines
17 KiB
C
/* user_cmd.c - 蓝牙串口调试命令处理
|
||
*
|
||
* 通过 USART1 接收简单文本命令,用于现场调试:
|
||
* RESET/OTA - 复位整机
|
||
* WIFIRESET - WiFi模块 AT+RESTORE 忘掉已存热点(测试SmartConfig) + 复位
|
||
* INFO - 打印 MQTT 配置信息
|
||
* SETMQTT <ID> <用户名> <密码> - 灌入设备身份(写 EEPROM,保存后自动重启生效)
|
||
* SETIP <ip> <port> - 修改服务器地址/端口(写 EEPROM,保存后自动重启生效)
|
||
* MQTTINFO - 查询当前 MQTT 配置
|
||
* FACTORY - 恢复出厂:清空 EEPROM 全部配置,重启进入待配置模式
|
||
* SETWIFI ssid 密码 - 配置 WiFi 固定热点(写 EEPROM,保存后自动重启生效)
|
||
* WIFIINFO - 查询当前 WiFi 热点配置
|
||
* WIFICLEAR - 清除 SETWIFI 配置的热点,回到编译默认(自动重启生效)
|
||
* FEEDSTART 投料量KG - 带秤模式:开始投喂(如 FEEDSTART 1.5)
|
||
* FEEDSTOP - 停止投喂;FEED - 查询投喂状态
|
||
* STATUS - 打印继电器状态
|
||
* R1ON ~ R4OFF - 单路继电器开关
|
||
* ALLON / ALLOFF - 全部继电器开关
|
||
* HISTORY - 打印最近 10 条重启记录(开机不再自动打印)
|
||
* HELP - 显示支持命令
|
||
*/
|
||
|
||
#include "user_cmd.h"
|
||
#include <stdlib.h>
|
||
#include "ble_at.h"
|
||
#include "app_common.h"
|
||
#include "relay.h"
|
||
#include "ext_relay.h"
|
||
#include "24c02.h"
|
||
#include "uart.h"
|
||
#include "log.h"
|
||
#include "network.h"
|
||
#include "net_wifi.h"
|
||
#include "esp8266.h"
|
||
#include "reset_log.h"
|
||
#include "feed_scale.h"
|
||
#include "air780e.h"
|
||
#include "hlw8032.h"
|
||
|
||
/* 本地命令字符串不区分大小写比较 */
|
||
static int cmd_is(const char *a, const char *b)
|
||
{
|
||
while (*a && *b) {
|
||
char ca = *a, cb = *b;
|
||
if (ca >= 'A' && ca <= 'Z') ca += 'a' - 'A';
|
||
if (cb >= 'A' && cb <= 'Z') cb += 'a' - 'A';
|
||
if (ca != cb) return 0;
|
||
a++; b++;
|
||
}
|
||
return (*a == 0 && *b == 0);
|
||
}
|
||
|
||
/* 通过蓝牙串口直接控制单个继电器,并保存/上报状态 */
|
||
static void relay_set(uint8_t ch, uint8_t on)
|
||
{
|
||
if (ch < 1 || ch > 4) return;
|
||
|
||
relaySet(ch, on);
|
||
log_info("> BT: SW%d %s", ch, on ? "开" : "关");
|
||
eepromWriteData(102, &MqttInfoStr.Relay_State[0], 7);
|
||
relayRequestReport();
|
||
}
|
||
|
||
/* 不区分大小写的命令前缀比较:cmd 以 prefix 开头返回 1 */
|
||
static int cmd_prefix_is(const char *cmd, const char *prefix)
|
||
{
|
||
while (*prefix) {
|
||
char ca = *cmd, cb = *prefix;
|
||
if (ca == 0) return 0;
|
||
if (ca >= 'A' && ca <= 'Z') ca += 'a' - 'A';
|
||
if (cb >= 'A' && cb <= 'Z') cb += 'a' - 'A';
|
||
if (ca != cb) return 0;
|
||
cmd++; prefix++;
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
/* 解析命令参数:空格分隔(如 "SETMQTT id user pass")。
|
||
* 返回参数个数,t 为输出(每个参数上限 cap-1 字符) */
|
||
static int parse_tokens(const char *s, char t[][20], int cap)
|
||
{
|
||
int n = 0;
|
||
for (;;) {
|
||
while (*s == ' ') s++; /* 跳过分隔空格 */
|
||
if (*s == 0) break;
|
||
if (n >= 3) return 4; /* 参数过多 */
|
||
int i = 0;
|
||
while (*s && *s != ' ' && i < cap - 1) t[n][i++] = *s++;
|
||
t[n][i] = 0;
|
||
n++;
|
||
}
|
||
return n;
|
||
}
|
||
|
||
/* 校验字符串:非空、长度 < cap、仅字母数字 */
|
||
static int token_valid(const char *t, int cap)
|
||
{
|
||
int len = (int)strlen(t);
|
||
if (len <= 0 || len >= cap) return 0;
|
||
for (const char *p = t; *p; p++) {
|
||
if (!((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z'))) return 0;
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
/* WiFi 名称/密码校验:非空、长度 < cap、可打印非空格字符 */
|
||
static int wifi_token_valid(const char *t, int cap)
|
||
{
|
||
int len = (int)strlen(t);
|
||
if (len <= 0 || len >= cap) return 0;
|
||
for (const char *p = t; *p; p++) {
|
||
if (*p < 0x21 || *p > 0x7E) return 0;
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
void userCmdInit(void)
|
||
{
|
||
/* 无需额外初始化 */
|
||
}
|
||
|
||
/* 处理 USART1 蓝牙调试命令 */
|
||
void process_usart1_command(void)
|
||
{
|
||
const char *cmd = USART1_GetCommand();
|
||
if (!cmd) return;
|
||
|
||
/* 去掉首尾空格:手机输入法/APP 容易带尾巴,命令判断更宽容 */
|
||
while (*cmd == ' ') cmd++;
|
||
{
|
||
char *end = (char *)cmd + strlen(cmd);
|
||
while (end > cmd && (end[-1] == ' ' || end[-1] == '\r' || end[-1] == '\n')) *--end = 0;
|
||
if (*cmd == 0) return;
|
||
}
|
||
|
||
/* 产品模式查询/切换:SCALE 查询,SCALE0=四路继电器(无秤),SCALE1=称重投料(带秤),切换后自动重启生效 */
|
||
if (cmd_is(cmd, "SCALE")) {
|
||
log_info("> BT: 产品模式 %s", g_feed_scale_on ? "SCALE1 称重投料(带秤)" : "SCALE0 四路继电器(无秤)");
|
||
return;
|
||
}
|
||
if (cmd_is(cmd, "SCALE0") || cmd_is(cmd, "SCALE1")) {
|
||
uint8_t on = (cmd[5] == '1') ? 1 : 0;
|
||
if (on == g_feed_scale_on) {
|
||
log_info("> BT: 已是该模式,无需切换");
|
||
return;
|
||
}
|
||
feed_scale_set_mode(on);
|
||
log_warn("> BT: 产品模式已切到 %s,重启生效...", on ? "称重投料(带秤)" : "四路继电器(无秤)");
|
||
reset_log_mark(RSN_CMD_RESET);
|
||
HAL_Delay(200);
|
||
NVIC_SystemReset();
|
||
return;
|
||
}
|
||
|
||
/* GPS 定位开关:GPS 查询,GPS0=关闭,GPS1=开启,切换后自动重启生效 */
|
||
if (cmd_is(cmd, "GPS")) {
|
||
log_info("> BT: GPS 定位 %s", g_gps_on ? "开启(GPS1)" : "关闭(GPS0)");
|
||
return;
|
||
}
|
||
if (cmd_is(cmd, "GPS0") || cmd_is(cmd, "GPS1")) {
|
||
uint8_t on = (cmd[3] == '1') ? 1 : 0;
|
||
if (on == g_gps_on) {
|
||
log_info("> BT: 已是该状态,无需切换");
|
||
return;
|
||
}
|
||
gps_set_mode(on);
|
||
log_warn("> BT: GPS 定位已切到 %s,重启生效...", on ? "开启" : "关闭");
|
||
reset_log_mark(RSN_CMD_RESET);
|
||
HAL_Delay(200);
|
||
NVIC_SystemReset();
|
||
return;
|
||
}
|
||
|
||
/* 累计电能清零(EEPROM 同步落盘,无需重启) */
|
||
if (cmd_is(cmd, "ENCLR")) {
|
||
hlw8032_clear();
|
||
log_warn("> BT: 累计电能已清零");
|
||
return;
|
||
}
|
||
|
||
if (cmd_is(cmd, "RESET")) {
|
||
log_warn("> USART1: 收到 RESET 命令,正在重启...");
|
||
reset_log_mark(RSN_CMD_RESET);
|
||
HAL_Delay(100);
|
||
NVIC_SystemReset();
|
||
}
|
||
else if (cmd_is(cmd, "INFO")) {
|
||
log_info("> BT INFO: 版本=%u, 服务器=%s:%d, 客户端=%s",
|
||
MqttInfoStr.Ver, MqttInfoStr.ServerIP,
|
||
MqttInfoStr.ServerPort, MqttInfoStr.ClientID);
|
||
}
|
||
else if (cmd_prefix_is(cmd, "SETMQTT")) {
|
||
char args[3][20] = {{0}};
|
||
char *id = args[0], *user = args[1], *pass = args[2];
|
||
int n = parse_tokens(cmd + 7, args, 20);
|
||
if (n != 3 || !token_valid(id, sizeof(MqttInfoStr.ClientID)) ||
|
||
!token_valid(user, sizeof(MqttInfoStr.Username)) ||
|
||
!token_valid(pass, sizeof(MqttInfoStr.Passward))) {
|
||
log_warn("> BT: 格式/字符不对,用法: SETMQTT <ID> <用户名> <密码>(仅字母数字,各不超过19位)");
|
||
return;
|
||
}
|
||
strcpy(MqttInfoStr.ClientID, id);
|
||
strcpy(MqttInfoStr.Username, user);
|
||
strcpy(MqttInfoStr.Passward, pass);
|
||
MqttInfoStr.Magic = EEPROM_MAGIC;
|
||
eepromWriteData(0, &MqttInfoStr, MQTT_STRUCT_LEN);
|
||
log_info("> BT: 身份已保存 ID=%s 用户=%s 密码=%s,自动重启生效...", id, user, pass);
|
||
HAL_Delay(1000); /* 给蓝牙留出发送时间 */
|
||
NVIC_SystemReset();
|
||
}
|
||
else if (cmd_prefix_is(cmd, "SETIP")) {
|
||
char args[3][20] = {{0}};
|
||
int port = 0, dots = 0;
|
||
int n = parse_tokens(cmd + 5, args, 20);
|
||
char *ip = args[0];
|
||
if (n == 2) port = atoi(args[1]);
|
||
for (const char *q = ip; *q; q++) {
|
||
if (*q == '.') dots++;
|
||
else if (*q < '0' || *q > '9') { dots = -1; break; }
|
||
}
|
||
if (n != 2 || dots != 3 || port < 1 || port > 65535) {
|
||
log_warn("> BT: 格式不对,用法: SETIP <ip> <port>(如 SETIP 58.17.14.95 1880)");
|
||
return;
|
||
}
|
||
strcpy(MqttInfoStr.ServerIP, ip);
|
||
MqttInfoStr.ServerPort = (uint16_t)port;
|
||
MqttInfoStr.Magic = EEPROM_MAGIC;
|
||
eepromWriteData(0, &MqttInfoStr, MQTT_STRUCT_LEN);
|
||
log_info("> BT: 服务器已保存 %s:%d,自动重启生效...", ip, port);
|
||
HAL_Delay(1000);
|
||
NVIC_SystemReset();
|
||
}
|
||
else if (cmd_is(cmd, "MQTTINFO")) {
|
||
log_info("> BT MQTT: 状态=%s", g_mqtt_configured ? "已配置" : "未配置");
|
||
log_info("> BT MQTT: 服务器=%s:%d", MqttInfoStr.ServerIP, MqttInfoStr.ServerPort);
|
||
log_info("> BT MQTT: ID=%s 用户=%s 密码=%s 版本=%u",
|
||
MqttInfoStr.ClientID[0] ? MqttInfoStr.ClientID : "(空)",
|
||
MqttInfoStr.Username[0] ? MqttInfoStr.Username : "(空)",
|
||
MqttInfoStr.Passward[0] ? MqttInfoStr.Passward : "(空)",
|
||
MqttInfoStr.Ver);
|
||
}
|
||
else if (cmd_is(cmd, "FACTORY")) {
|
||
/* 恢复出厂:整片 EEPROM 写 0xFF(身份/服务器/继电器记忆/模式/电能累计等全清),
|
||
* 重启后走"全新板"路径:Magic 无效 -> 待配置模式,版本号归 0 */
|
||
log_warn("> BT: 恢复出厂设置,正在清空 EEPROM...");
|
||
uint8_t ff[16];
|
||
memset(ff, 0xFF, sizeof(ff));
|
||
for (uint16_t addr = 0; addr < 256; addr += sizeof(ff)) {
|
||
eepromWriteData((uint8_t)addr, ff, sizeof(ff));
|
||
}
|
||
log_warn("> BT: 已清空,重启进入待配置模式");
|
||
HAL_Delay(500);
|
||
NVIC_SystemReset();
|
||
}
|
||
else if (cmd_prefix_is(cmd, "SETWIFI")) {
|
||
char args[3][20] = {{0}};
|
||
int n = parse_tokens(cmd + 7, args, 20);
|
||
if (n != 2 || !wifi_token_valid(args[0], 20) || !wifi_token_valid(args[1], 20)) {
|
||
log_warn("> BT: 格式不对,用法: SETWIFI 名称 密码(空格分隔,各不超过19位)");
|
||
return;
|
||
}
|
||
uint8_t buf[WIFI_CFG_STR_LEN];
|
||
uint8_t magic = WIFI_CFG_MAGIC;
|
||
eepromWriteData(WIFI_CFG_MAGIC_ADDR, &magic, 1);
|
||
memset(buf, 0, sizeof(buf)); strcpy((char *)buf, args[0]);
|
||
eepromWriteData(WIFI_CFG_SSID_ADDR, buf, sizeof(buf));
|
||
memset(buf, 0, sizeof(buf)); strcpy((char *)buf, args[1]);
|
||
eepromWriteData(WIFI_CFG_PASS_ADDR, buf, sizeof(buf));
|
||
log_info("> BT: WiFi 热点已保存 '%s',自动重启生效...", args[0]);
|
||
HAL_Delay(1000);
|
||
NVIC_SystemReset();
|
||
}
|
||
else if (cmd_is(cmd, "WIFIINFO")) {
|
||
uint8_t magic = 0;
|
||
char ssid[WIFI_CFG_STR_LEN] = {0}, pass[WIFI_CFG_STR_LEN] = {0};
|
||
eepromReadData(WIFI_CFG_MAGIC_ADDR, &magic, 1);
|
||
if (magic == WIFI_CFG_MAGIC) {
|
||
eepromReadData(WIFI_CFG_SSID_ADDR, ssid, WIFI_CFG_STR_LEN);
|
||
eepromReadData(WIFI_CFG_PASS_ADDR, pass, WIFI_CFG_STR_LEN);
|
||
log_info("> BT WiFi: EEPROM 配置 名称=%s 密码=%s", ssid, pass);
|
||
} else {
|
||
log_info("> BT WiFi: 未配置(用编译默认热点 '%s'),SETWIFI 名称 密码 可修改", WIFI_SSID);
|
||
}
|
||
}
|
||
else if (cmd_is(cmd, "WIFICLEAR")) {
|
||
/* 清掉 EEPROM 里的 SETWIFI 配置(magic 置无效),回到编译默认热点,自动重启生效 */
|
||
uint8_t magic = 0;
|
||
eepromReadData(WIFI_CFG_MAGIC_ADDR, &magic, 1);
|
||
if (magic != WIFI_CFG_MAGIC) {
|
||
log_info("> BT: 本来就没有 SETWIFI 配置(当前用编译默认 '%s')", WIFI_SSID);
|
||
return;
|
||
}
|
||
magic = 0xFF;
|
||
eepromWriteData(WIFI_CFG_MAGIC_ADDR, &magic, 1);
|
||
log_info("> BT: SETWIFI 配置已清除,回到编译默认 '%s',自动重启...", WIFI_SSID);
|
||
HAL_Delay(1000);
|
||
NVIC_SystemReset();
|
||
}
|
||
else if (cmd_prefix_is(cmd, "FEEDSTART")) {
|
||
if (!g_feed_scale_on) { log_warn("> BT: 当前无秤模式,控制继电器 1 请用 R1ON/R1OFF"); return; }
|
||
char args[3][20] = {{0}};
|
||
int n = parse_tokens(cmd + 9, args, 20);
|
||
float kg = (n == 1) ? (float)atof(args[0]) : 0.0f;
|
||
uint16_t w100 = (uint16_t)(kg * 10.0f + 0.5f);
|
||
if (n != 1 || kg <= 0.0f || w100 < FEED_SCALE_ONCEWT_MIN || w100 > FEED_SCALE_ONCEWT_MAX) {
|
||
log_warn("> BT: 格式不对,用法: FEEDSTART 投料量KG(0.1~500.0,如 FEEDSTART 1.5)");
|
||
return;
|
||
}
|
||
log_info("> BT: 请求开始投喂 %.1fKG", (double)kg);
|
||
feedScaleStart(w100);
|
||
}
|
||
else if (cmd_is(cmd, "FEEDSTOP")) {
|
||
feedScaleStop();
|
||
log_info("> BT: 已请求停止投喂");
|
||
}
|
||
else if (cmd_is(cmd, "FEED")) {
|
||
static const char *sts[] = {"空闲", "投喂中", "投喂完成", "异常结束"};
|
||
FeedScaleState st = feedScaleGetState();
|
||
log_info("> BT FEED: 状态=%s 剩余=%.1fKG 单次=%.1fKG 已减=%.1fKG",
|
||
sts[(int)st],
|
||
(double)(feedScaleGetWeight() / 10.0f),
|
||
(double)(feedScaleGetOnceWeight() / 10.0f),
|
||
(double)(feedScaleGetReduced() / 10.0f));
|
||
}
|
||
else if (cmd_is(cmd, "R1ON")) { relay_set(1, 1); }
|
||
else if (cmd_is(cmd, "R1OFF")) { relay_set(1, 0); }
|
||
else if (cmd_is(cmd, "R2ON")) { relay_set(2, 1); }
|
||
else if (cmd_is(cmd, "R2OFF")) { relay_set(2, 0); }
|
||
else if (cmd_is(cmd, "R3ON")) { relay_set(3, 1); }
|
||
else if (cmd_is(cmd, "R3OFF")) { relay_set(3, 0); }
|
||
else if (cmd_is(cmd, "R4ON")) { relay_set(4, 1); }
|
||
else if (cmd_is(cmd, "R4OFF")) { relay_set(4, 0); }
|
||
else if (cmd_is(cmd, "R5ON")) { ext_relay_cmd(1, 1, NULL); } /* 485 扩展继电器板 */
|
||
else if (cmd_is(cmd, "R5OFF")) { ext_relay_cmd(1, 0, NULL); }
|
||
else if (cmd_is(cmd, "R6ON")) { ext_relay_cmd(2, 1, NULL); }
|
||
else if (cmd_is(cmd, "R6OFF")) { ext_relay_cmd(2, 0, NULL); }
|
||
else if (cmd_is(cmd, "R7ON")) { ext_relay_cmd(3, 1, NULL); }
|
||
else if (cmd_is(cmd, "R7OFF")) { ext_relay_cmd(3, 0, NULL); }
|
||
else if (cmd_is(cmd, "R8ON")) { ext_relay_cmd(4, 1, NULL); }
|
||
else if (cmd_is(cmd, "R8OFF")) { ext_relay_cmd(4, 0, NULL); }
|
||
else if (cmd_is(cmd, "ALLON")) {
|
||
relay_set(1, 1); relay_set(2, 1); relay_set(3, 1); relay_set(4, 1);
|
||
}
|
||
else if (cmd_is(cmd, "ALLOFF")) {
|
||
relay_set(1, 0); relay_set(2, 0); relay_set(3, 0); relay_set(4, 0);
|
||
}
|
||
else if (cmd_is(cmd, "STATUS")) {
|
||
log_info("> BT STATUS: SW1=%s, SW2=%s, SW3=%s, SW4=%s",
|
||
MqttInfoStr.Relay_State[1] ? "开" : "关",
|
||
MqttInfoStr.Relay_State[2] ? "开" : "关",
|
||
MqttInfoStr.Relay_State[3] ? "开" : "关",
|
||
MqttInfoStr.Relay_State[4] ? "开" : "关");
|
||
if (ext_relay_online()) {
|
||
uint8_t m = ext_relay_state_mask();
|
||
log_info("> BT STATUS: 扩展板 SW5=%s, SW6=%s, SW7=%s, SW8=%s (故障=%02X)",
|
||
(m & 1) ? "开" : "关",
|
||
(m & 2) ? "开" : "关",
|
||
(m & 4) ? "开" : "关",
|
||
(m & 8) ? "开" : "关",
|
||
ext_relay_fault_mask());
|
||
} else {
|
||
log_info("> BT STATUS: 扩展板离线/未接");
|
||
}
|
||
}
|
||
else if (cmd_is(cmd, "OTA")) {
|
||
log_info("> BT OTA: 重启进入 BootLoader 检查升级");
|
||
reset_log_mark(RSN_CMD_OTA);
|
||
HAL_Delay(100);
|
||
NVIC_SystemReset();
|
||
}
|
||
else if (cmd_is(cmd, "WIFIRESET")) {
|
||
/* WiFi 模块 AT+RESTORE 恢复出厂(忘掉已保存的热点),用于测试 SmartConfig;
|
||
* 仅 WiFi 通道激活时才操作模块(UART4 与 4G 共享接收缓冲,
|
||
* 4G 模式下动 UART4 会干扰 4G 数据),随后整机复位走完整重连流程 */
|
||
if (NET_GetActiveBackend() == NET_BACKEND_WIFI) {
|
||
log_warn("> BT WIFIRESET: 已安排 WiFi 恢复出厂设置"); g_wifi_restore_req = 1;
|
||
} else {
|
||
log_warn("> BT WIFIRESET: 4G 模式,不操作 WiFi 模块,仅重启");
|
||
reset_log_mark(RSN_CMD_RECOVERY);
|
||
HAL_Delay(100);
|
||
NVIC_SystemReset();
|
||
}
|
||
}
|
||
else if (cmd_is(cmd, "BLESET")) {
|
||
log_info("> BT: 强制重新设置蓝牙名称/UUID");
|
||
ble_force_setup();
|
||
}
|
||
else if (cmd_is(cmd, "LOGTRACE")) { log_set_level(LOG_TRACE); log_info("> BT: 日志等级 TRACE"); }
|
||
else if (cmd_is(cmd, "LOGDEBUG")) { log_set_level(LOG_DEBUG); log_info("> BT: 日志等级 DEBUG"); }
|
||
else if (cmd_is(cmd, "LOGINFO")) { log_set_level(LOG_INFO); log_info("> BT: 日志等级 INFO"); }
|
||
else if (cmd_is(cmd, "LOGWARN")) { log_set_level(LOG_WARN); log_info("> BT: 日志等级 WARN"); }
|
||
else if (cmd_is(cmd, "LOGERROR")) { log_set_level(LOG_ERROR); log_info("> BT: 日志等级 ERROR"); }
|
||
else if (cmd_is(cmd, "LOGFATAL")) { log_set_level(LOG_FATAL); log_info("> BT: 日志等级 FATAL"); }
|
||
else if (cmd_is(cmd, "LOG")) {
|
||
static const char *lvs[] = {"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"};
|
||
log_info("> BT: 当前日志等级 %s", lvs[(int)log_get_level()]);
|
||
}
|
||
else if (cmd_is(cmd, "HISTORY")) {
|
||
reset_log_print_history();
|
||
}
|
||
else if (cmd_is(cmd, "HELP")) {
|
||
log_info("===蓝牙调试命令(空格分隔参数)===");
|
||
log_info("RESET - 系统复位");
|
||
log_info("INFO - 打印 MQTT 配置简况");
|
||
log_info("MQTTINFO - 查询 MQTT 配置详情");
|
||
log_info("SETMQTT ID 用户名 密码 - 灌入设备身份(保存后自动重启)");
|
||
log_info("SETIP ip 端口 - 修改服务器地址/端口(保存后自动重启)");
|
||
log_info("FACTORY - 恢复出厂:清空 EEPROM 全部配置并重启");
|
||
log_info("STATUS - 打印四路继电器状态");
|
||
log_info("R1ON/R1OFF~R4ON/R4OFF - 单路继电器开/关");
|
||
log_info("ALLON/ALLOFF - 全部继电器开/关");
|
||
log_info("OTA - 重启进 BootLoader 检查升级");
|
||
log_info("WIFICLEAR - 清除 SETWIFI 配置的热点,回到编译默认(自动重启)");
|
||
log_info("WIFIRESET - WiFi 模块恢复出厂(忘掉 SmartConfig 已存热点)并复位");
|
||
log_info("BLESET - 强制重设蓝牙名称/GATT UUID");
|
||
log_info("SCALE - 查询产品模式;SCALE0 无秤 / SCALE1 带秤(切换后自动重启)");
|
||
log_info("GPS - 查询 GPS 开关;GPS0 关 / GPS1 开(切换后自动重启)");
|
||
log_info("ENCLR - 累计电能清零");
|
||
log_info("SETWIFI 名称 密码 - 配置 WiFi 固定热点(保存后自动重启)");
|
||
log_info("WIFIINFO - 查询 WiFi 热点配置");
|
||
log_info("FEEDSTART 投料量KG - 带秤模式开始投喂;FEEDSTOP 停止;FEED 查询状态");
|
||
log_info("LOG - 查询日志等级;LOGTRACE~LOGFATAL 六档设置(断电保存)");
|
||
log_info("HISTORY - 打印最近 10 条重启记录(原因+运行时长)");
|
||
log_info("HELP - 显示本帮助");
|
||
log_info("========= END =========");
|
||
}
|
||
else {
|
||
log_warn("> BT: 未知命令 %s", cmd);
|
||
}
|
||
}
|