feat(ux): improve wifi, voice, and print feedback flows

This commit is contained in:
admin
2026-03-10 13:05:10 +08:00
parent b59c69fb3f
commit 559df3b570
15 changed files with 508 additions and 33 deletions

View File

@@ -337,6 +337,21 @@
status_connect_ok: '连接成功,正在关闭配网页面...',
status_connect_failed: '连接失败:{error}。请重试。',
status_request_failed: '请求失败,请重试。',
error_invalid_payload: '提交内容无效',
error_read_failed: '设备读取请求失败',
error_ssid_required: 'SSID 不能为空',
error_password_too_short: '密码至少需要 8 位',
error_wrong_password: '密码错误',
error_no_ap_found: '未找到该 Wi-Fi',
error_signal_too_weak: '信号太弱,请靠近路由器',
error_ap_not_responding: '路由器无响应',
error_association_failed: '连接被路由器拒绝',
error_ap_security_unsupported: '路由器加密方式暂不支持',
error_connect_timeout: '连接超时',
error_wifi_unavailable: '设备 Wi-Fi 暂不可用',
error_save_failed: '连接成功但保存失败,请重试',
error_connect_failed: '无法连接到该 Wi-Fi',
error_unknown: '未知错误',
signal_unit: 'dBm'
},
'en-US': {
@@ -359,6 +374,21 @@
status_connect_ok: 'Connected successfully. Closing this provisioning page...',
status_connect_failed: 'Connection failed: {error}. Please try again.',
status_request_failed: 'Request failed. Please try again.',
error_invalid_payload: 'Invalid request payload',
error_read_failed: 'Device failed to read request',
error_ssid_required: 'SSID is required',
error_password_too_short: 'Password must be at least 8 characters',
error_wrong_password: 'Wrong password',
error_no_ap_found: 'Wi-Fi network not found',
error_signal_too_weak: 'Signal is too weak',
error_ap_not_responding: 'Router is not responding',
error_association_failed: 'Router rejected the connection',
error_ap_security_unsupported: 'Wi-Fi security mode is unsupported',
error_connect_timeout: 'Connection timed out',
error_wifi_unavailable: 'Device Wi-Fi is unavailable',
error_save_failed: 'Connected, but failed to save credentials',
error_connect_failed: 'Unable to connect to this Wi-Fi',
error_unknown: 'Unknown error',
signal_unit: 'dBm'
}
};
@@ -402,6 +432,18 @@
setStatusText(trWithParams(key, params), type);
}
function mapProvisionError(code) {
if (!code) {
return tr('error_unknown');
}
const key = 'error_' + String(code);
const mapped = tr(key);
if (mapped === key) {
return tr('error_connect_failed');
}
return mapped;
}
function decodeSsid(value) {
try {
return decodeURIComponent(value);
@@ -562,7 +604,9 @@
return;
}
setStatusKey('status_connect_failed', 'err', { error: data.error || 'unknown' });
setStatusKey('status_connect_failed', 'err', {
error: mapProvisionError(data.error)
});
} catch (_err) {
setStatusKey('status_request_failed', 'err');
}

View File

@@ -16,6 +16,10 @@ esp_err_t platform_bootstrap_init(void);
// ---------- wifi_manager ----------
typedef enum {
WIFI_MANAGER_EVENT_PROVISIONING_STARTED = 0,
WIFI_MANAGER_EVENT_STA_CONNECTING,
WIFI_MANAGER_EVENT_STA_CONNECTED,
WIFI_MANAGER_EVENT_STA_CONNECT_FAILED,
WIFI_MANAGER_EVENT_STA_DISCONNECTED,
} wifi_manager_event_t;
typedef void (*wifi_manager_event_cb_t)(wifi_manager_event_t event, void *user_data);

View File

@@ -18,7 +18,7 @@
static const char *TAG = "lcd_module";
#define ST7789_SPI_HOST SPI2_HOST
#define LCD_PREVIEW_TIMEOUT_MS_DEFAULT 200
#define LCD_PREVIEW_TIMEOUT_MS_DEFAULT 3000
#define LCD_LOCK_TIMEOUT_MS 1000
#define LCD_DEFAULT_DRAW_LINES 20
#define LCD_PREVIEW_FADE_DURATION_MS 150

View File

@@ -66,6 +66,8 @@ static esp_netif_t *s_ap_netif;
static httpd_handle_t s_prov_httpd;
static esp_event_handler_instance_t s_wifi_event_inst;
static esp_event_handler_instance_t s_ip_event_inst;
static uint8_t s_last_sta_disconnect_reason;
static bool s_last_sta_disconnect_reason_valid;
static void wifi_manager_notify_event(wifi_manager_event_t event) {
wifi_manager_event_cb_t cb = s_event_cb;
@@ -75,6 +77,87 @@ static void wifi_manager_notify_event(wifi_manager_event_t event) {
cb(event, s_event_cb_user_data);
}
static const char *wifi_manager_error_from_disconnect_reason(uint8_t reason) {
#ifdef WIFI_REASON_AUTH_EXPIRE
if (reason == WIFI_REASON_AUTH_EXPIRE) {
return "wrong_password";
}
#endif
#ifdef WIFI_REASON_AUTH_FAIL
if (reason == WIFI_REASON_AUTH_FAIL) {
return "wrong_password";
}
#endif
#ifdef WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT
if (reason == WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT) {
return "wrong_password";
}
#endif
#ifdef WIFI_REASON_HANDSHAKE_TIMEOUT
if (reason == WIFI_REASON_HANDSHAKE_TIMEOUT) {
return "wrong_password";
}
#endif
#ifdef WIFI_REASON_ASSOC_FAIL
if (reason == WIFI_REASON_ASSOC_FAIL) {
return "association_failed";
}
#endif
#ifdef WIFI_REASON_CONNECTION_FAIL
if (reason == WIFI_REASON_CONNECTION_FAIL) {
return "association_failed";
}
#endif
#ifdef WIFI_REASON_NO_AP_FOUND
if (reason == WIFI_REASON_NO_AP_FOUND) {
return "no_ap_found";
}
#endif
#ifdef WIFI_REASON_NO_AP_FOUND_IN_AUTHMODE_THRESHOLD
if (reason == WIFI_REASON_NO_AP_FOUND_IN_AUTHMODE_THRESHOLD) {
return "ap_security_unsupported";
}
#endif
#ifdef WIFI_REASON_NO_AP_FOUND_IN_RSSI_THRESHOLD
if (reason == WIFI_REASON_NO_AP_FOUND_IN_RSSI_THRESHOLD) {
return "signal_too_weak";
}
#endif
#ifdef WIFI_REASON_BEACON_TIMEOUT
if (reason == WIFI_REASON_BEACON_TIMEOUT) {
return "ap_not_responding";
}
#endif
#ifdef WIFI_REASON_ASSOC_EXPIRE
if (reason == WIFI_REASON_ASSOC_EXPIRE) {
return "ap_not_responding";
}
#endif
#ifdef WIFI_REASON_ASSOC_LEAVE
if (reason == WIFI_REASON_ASSOC_LEAVE) {
return "ap_not_responding";
}
#endif
return "connect_failed";
}
static const char *wifi_manager_resolve_connect_error_code(esp_err_t connect_rc) {
if (connect_rc == ESP_ERR_TIMEOUT) {
return "connect_timeout";
}
if (connect_rc == ESP_ERR_INVALID_STATE) {
return "wifi_unavailable";
}
if (connect_rc != ESP_FAIL) {
return "connect_failed";
}
if (s_last_sta_disconnect_reason_valid) {
return wifi_manager_error_from_disconnect_reason(s_last_sta_disconnect_reason);
}
return "connect_failed";
}
static void wifi_manager_apply_sta_throughput_profile(void) {
const uint8_t protocol = WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N;
esp_err_t proto_rc = esp_wifi_set_protocol(WIFI_IF_STA, protocol);
@@ -175,11 +258,15 @@ static void wifi_event_handler(void *arg,
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
s_ready = false;
if (!s_started || !s_sta_reconnect_enabled) {
wifi_manager_notify_event(WIFI_MANAGER_EVENT_STA_DISCONNECTED);
return;
}
wifi_event_sta_disconnected_t *disc = (wifi_event_sta_disconnected_t *)event_data;
uint8_t reason = disc != NULL ? disc->reason : 0;
s_last_sta_disconnect_reason = reason;
s_last_sta_disconnect_reason_valid = (reason != 0);
wifi_manager_notify_event(WIFI_MANAGER_EVENT_STA_DISCONNECTED);
if (s_retry_num < CONFIG_TQ_WIFI_MAXIMUM_RETRY) {
(void)esp_wifi_connect();
@@ -208,6 +295,7 @@ static void wifi_event_handler(void *arg,
if (s_wifi_event_group != NULL) {
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
wifi_manager_notify_event(WIFI_MANAGER_EVENT_STA_CONNECTED);
}
}
@@ -476,6 +564,8 @@ static esp_err_t wifi_manager_connect_sta(const wifi_sta_credentials_t *creds, b
xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT);
s_retry_num = 0;
s_ready = false;
s_last_sta_disconnect_reason = 0;
s_last_sta_disconnect_reason_valid = false;
s_sta_reconnect_enabled = false;
esp_err_t err = esp_wifi_disconnect();
@@ -486,23 +576,28 @@ static esp_err_t wifi_manager_connect_sta(const wifi_sta_credentials_t *creds, b
err = esp_wifi_set_mode(keep_softap ? WIFI_MODE_APSTA : WIFI_MODE_STA);
if (err != ESP_OK) {
wifi_manager_notify_event(WIFI_MANAGER_EVENT_STA_CONNECT_FAILED);
return err;
}
err = esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
if (err != ESP_OK) {
wifi_manager_notify_event(WIFI_MANAGER_EVENT_STA_CONNECT_FAILED);
return err;
}
err = esp_wifi_start();
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) {
wifi_manager_notify_event(WIFI_MANAGER_EVENT_STA_CONNECT_FAILED);
return err;
}
err = esp_wifi_connect();
if (err != ESP_OK && err != ESP_ERR_WIFI_CONN) {
wifi_manager_notify_event(WIFI_MANAGER_EVENT_STA_CONNECT_FAILED);
return err;
}
wifi_manager_notify_event(WIFI_MANAGER_EVENT_STA_CONNECTING);
ESP_LOGI(TAG, "trying to connect to SSID:%s", creds->ssid);
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
@@ -526,10 +621,12 @@ static esp_err_t wifi_manager_connect_sta(const wifi_sta_credentials_t *creds, b
if (bits & WIFI_FAIL_BIT) {
ESP_LOGW(TAG, "failed to connect to SSID:%s", creds->ssid);
wifi_manager_notify_event(WIFI_MANAGER_EVENT_STA_CONNECT_FAILED);
return ESP_FAIL;
}
ESP_LOGW(TAG, "Wi-Fi connect timeout, SSID:%s", creds->ssid);
wifi_manager_notify_event(WIFI_MANAGER_EVENT_STA_CONNECT_FAILED);
return ESP_ERR_TIMEOUT;
}
@@ -583,7 +680,9 @@ static esp_err_t wifi_manager_prov_submit_post_handler(httpd_req_t *req) {
esp_err_t err = wifi_manager_connect_sta(&creds, true);
if (err != ESP_OK) {
return wifi_manager_send_prov_json(req, false, "connect_failed");
return wifi_manager_send_prov_json(req,
false,
wifi_manager_resolve_connect_error_code(err));
}
err = wifi_manager_save_credentials(&creds);
@@ -789,6 +888,8 @@ esp_err_t wifi_manager_start(void) {
s_ready = false;
s_sta_reconnect_enabled = true;
s_provisioning_active = false;
s_last_sta_disconnect_reason = 0;
s_last_sta_disconnect_reason_valid = false;
if (s_wifi_event_group == NULL) {
s_wifi_event_group = xEventGroupCreate();
@@ -888,6 +989,8 @@ esp_err_t wifi_manager_stop(void) {
s_ready = false;
s_retry_num = 0;
s_sta_reconnect_enabled = false;
s_last_sta_disconnect_reason = 0;
s_last_sta_disconnect_reason_valid = false;
wifi_manager_stop_softap_provisioning();