Commit 8359d134 authored by 957dd's avatar 957dd

Merge branch 'feature/add_aboard_tts' into 'master'

无网络语音播报到45s一次加优化了wfii扫描 See merge request !130
parents 7200adca 8d1ec7b8
This diff is collapsed.
...@@ -18,6 +18,12 @@ int orange_pi_save_wifi(const char *ssid, const char *password); ...@@ -18,6 +18,12 @@ int orange_pi_save_wifi(const char *ssid, const char *password);
/* 保存并立即连接 WiFi(含满 10 个自动删最旧逻辑) */ /* 保存并立即连接 WiFi(含满 10 个自动删最旧逻辑) */
int orange_pi_connect_wifi(const char *ssid, const char *password); int orange_pi_connect_wifi(const char *ssid, const char *password);
/*
* 扫描周围 WiFi,与已保存的 NetworkManager 配置匹配,并优先连接信号最强的配置。
* 返回 1=已激活一个已保存网络,0=没有可用匹配或全部连接失败,-1=扫描失败。
*/
int device_wifi_connect_best_saved_visible(void);
/* ===== App WiFi 管理 (UDP 18888) 接口 ===== */ /* ===== App WiFi 管理 (UDP 18888) 接口 ===== */
/* 查询已保存 WiFi 列表,返回 cJSON 数组(调用方负责 cJSON_Delete): /* 查询已保存 WiFi 列表,返回 cJSON 数组(调用方负责 cJSON_Delete):
......
...@@ -82,7 +82,8 @@ static int init_worker_threads(void) ...@@ -82,7 +82,8 @@ static int init_worker_threads(void)
return thread_start_init(thread_exit_time, thread_mqtt_beat, return thread_start_init(thread_exit_time, thread_mqtt_beat,
thread_open_browser, thread_mqtt_reconnect, thread_open_browser, thread_mqtt_reconnect,
thread_time_calculation, thread_play_mp3, thread_time_calculation, thread_play_mp3,
thread_steering_control); thread_steering_control,
thread_wifi_offline_recovery);
} }
static const AppInitStep s_init_steps[] = { static const AppInitStep s_init_steps[] = {
......
...@@ -35,7 +35,7 @@ int device_shot_cooling_init(); ...@@ -35,7 +35,7 @@ int device_shot_cooling_init();
int thread_start_init(ThreadFunc thread_exit_time, ThreadFunc thread_mqtt_beat, int thread_start_init(ThreadFunc thread_exit_time, ThreadFunc thread_mqtt_beat,
ThreadFunc thread_open_browser, ThreadFunc thread_mqtt_reconnect, ThreadFunc thread_open_browser, ThreadFunc thread_mqtt_reconnect,
ThreadFunc thread_time_calculation, ThreadFunc thread_play_mp3, ThreadFunc thread_time_calculation, ThreadFunc thread_play_mp3,
ThreadFunc thread_steering_control); ThreadFunc thread_steering_control, ThreadFunc thread_wifi_recovery);
/*像服务器请求*/ /*像服务器请求*/
int request_date(); int request_date();
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include "webrtcpush_config.h" #include "webrtcpush_config.h"
#include "webrtcpush_run.h" #include "webrtcpush_run.h"
#define PTHREAD_MAX 7 #define PTHREAD_MAX 8
static pthread_t s_thread[PTHREAD_MAX]; // 全局线程句柄数组(或传参) static pthread_t s_thread[PTHREAD_MAX]; // 全局线程句柄数组(或传参)
...@@ -19,7 +19,8 @@ static void *s_args[PTHREAD_MAX] = {NULL}; ...@@ -19,7 +19,8 @@ static void *s_args[PTHREAD_MAX] = {NULL};
int thread_start_init(ThreadFunc thread_exit_time, ThreadFunc thread_mqtt_beat, int thread_start_init(ThreadFunc thread_exit_time, ThreadFunc thread_mqtt_beat,
ThreadFunc thread_open_browser, ThreadFunc thread_mqtt_reconnect, ThreadFunc thread_open_browser, ThreadFunc thread_mqtt_reconnect,
ThreadFunc thread_time_calculation, ThreadFunc thread_play_mp3,ThreadFunc thread_steering_control) ThreadFunc thread_time_calculation, ThreadFunc thread_play_mp3,
ThreadFunc thread_steering_control, ThreadFunc thread_wifi_recovery)
{ {
ThreadFunc thread_funcs[] = { ThreadFunc thread_funcs[] = {
...@@ -29,7 +30,8 @@ int thread_start_init(ThreadFunc thread_exit_time, ThreadFunc thread_mqtt_beat, ...@@ -29,7 +30,8 @@ int thread_start_init(ThreadFunc thread_exit_time, ThreadFunc thread_mqtt_beat,
thread_mqtt_reconnect, thread_mqtt_reconnect,
thread_time_calculation, thread_time_calculation,
thread_play_mp3, thread_play_mp3,
thread_steering_control}; thread_steering_control,
thread_wifi_recovery};
for (int i = 0; i < PTHREAD_MAX; i++) for (int i = 0; i < PTHREAD_MAX; i++)
{ {
......
...@@ -7,7 +7,7 @@ typedef void *(*ThreadFunc)(void *); ...@@ -7,7 +7,7 @@ typedef void *(*ThreadFunc)(void *);
int thread_start_init(ThreadFunc thread_exit_time, ThreadFunc thread_mqtt_beat, int thread_start_init(ThreadFunc thread_exit_time, ThreadFunc thread_mqtt_beat,
ThreadFunc thread_open_browser, ThreadFunc thread_mqtt_reconnect, ThreadFunc thread_open_browser, ThreadFunc thread_mqtt_reconnect,
ThreadFunc thread_time_calculation, ThreadFunc thread_play_mp3, ThreadFunc thread_time_calculation, ThreadFunc thread_play_mp3,
ThreadFunc thread_steering_control); ThreadFunc thread_steering_control, ThreadFunc thread_wifi_recovery);
void *thread_exit_time(void *arg) ;//异常停止线程 void *thread_exit_time(void *arg) ;//异常停止线程
void *thread_mqtt_beat(void *arg) ;//心跳线程 void *thread_mqtt_beat(void *arg) ;//心跳线程
......
#include "wifi_autoconfig.h" #include "wifi_autoconfig.h"
#include "main.h" #include "main.h"
#include "http_config_mqtt.h" #include "http_config_mqtt.h"
#include "device_wifi_manager.h"
#include "audioplay.h"
#include "cJSON.h" #include "cJSON.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -8,6 +10,10 @@ ...@@ -8,6 +10,10 @@
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h>
#define WIFI_OFFLINE_RECOVERY_INTERVAL_SEC 40
#define WIFI_RECOVERY_SETTLE_SEC 5
#define WIFI_RECOVERY_MAX_SWITCH_ATTEMPTS 3
static const char *s_audio_files[] = { static const char *s_audio_files[] = {
"noCameraDetected.mp3", "noCameraDetected.mp3",
"connectionFailed.mp3", "connectionFailed.mp3",
...@@ -155,24 +161,13 @@ static void build_lang_filepath(char *filepath, size_t size, const char *lang, c ...@@ -155,24 +161,13 @@ static void build_lang_filepath(char *filepath, size_t size, const char *lang, c
} }
static int try_play_filepath(const char *filepath) { static int try_play_filepath(const char *filepath) {
char cmd[512];
if (access(filepath, F_OK) != 0) { if (access(filepath, F_OK) != 0) {
return 0; return 0;
} }
if (is_command_available("ffplay")) { if (audioplay_file_with_browser_preempt(filepath, 1.0) == 0) {
snprintf(cmd, sizeof(cmd), "ffplay -nodisp -autoexit -loglevel quiet \"%s\"", filepath); my_zlog_debug("离线音频播放成功: %s", filepath);
if (system(cmd) == 0) {
my_zlog_debug("ffplay 播放成功: %s", filepath);
return 1;
}
}
if (is_command_available("paplay")) {
snprintf(cmd, sizeof(cmd), "paplay \"%s\"", filepath);
if (system(cmd) == 0) {
my_zlog_debug("paplay 播放成功: %s", filepath);
return 1; return 1;
} }
}
my_zlog_warn("音频播放失败: %s", filepath); my_zlog_warn("音频播放失败: %s", filepath);
return 0; return 0;
} }
...@@ -467,6 +462,48 @@ static int has_internet_connection() { ...@@ -467,6 +462,48 @@ static int has_internet_connection() {
return has_business_api_connection(); return has_business_api_connection();
} }
/* 一次完整的断网恢复周期:播报与扫描主动连接必须在同一个周期执行。 */
static int run_offline_recovery_cycle(void) {
my_zlog_warn("断网恢复: 开始 40 秒周期播报和已保存 WiFi 检测");
play_audio_file("connectionFailed.mp3");
for (int attempt = 0; attempt < WIFI_RECOVERY_MAX_SWITCH_ATTEMPTS; attempt++) {
int connect_result = device_wifi_connect_best_saved_visible();
if (connect_result <= 0)
break;
sleep(WIFI_RECOVERY_SETTLE_SEC);
if (has_internet_connection()) {
my_zlog_info("断网恢复: 已恢复互联网连接");
prepare_offline_audio_after_network();
play_audio_file("connectionSuccessful.mp3");
return 1;
}
my_zlog_warn("断网恢复: WiFi 已连接但互联网仍不可用,继续尝试其它已保存网络");
}
return 0;
}
void *thread_wifi_offline_recovery(void *arg) {
(void)arg;
my_zlog_info("断网恢复线程已启动,检测间隔=%d秒",
WIFI_OFFLINE_RECOVERY_INTERVAL_SEC);
while (1) {
time_t cycle_started = time(NULL);
if (!has_internet_connection())
run_offline_recovery_cycle();
time_t cycle_finished = time(NULL);
int elapsed = (int)difftime(cycle_finished, cycle_started);
int remaining = WIFI_OFFLINE_RECOVERY_INTERVAL_SEC - elapsed;
if (remaining > 0)
sleep((unsigned int)remaining);
}
return NULL;
}
// 尝试连接 WiFi // 尝试连接 WiFi
static int try_connect_wifi(const char *ssid, const char *password) { static int try_connect_wifi(const char *ssid, const char *password) {
char cmd[512]; char cmd[512];
...@@ -495,29 +532,23 @@ void check_and_autoconfig_wifi() { ...@@ -495,29 +532,23 @@ void check_and_autoconfig_wifi() {
my_zlog_warn("进入扫码循环,将每隔几秒提示一次..."); my_zlog_warn("进入扫码循环,将每隔几秒提示一次...");
const char *img_path = "/tmp/wifi_scan.jpg"; const char *img_path = "/tmp/wifi_scan.jpg";
time_t last_prompt_time = 0; time_t last_recovery_time = 0;
time_t last_camera_warning_time = 0;
// 首次播放
// play_audio_file("toScanQRCode.mp3"); // 改为进入循环后由定时逻辑触发(且会先检查网络)
last_prompt_time = 0; // 设为 0,确保进入循环第一次就会满足 difftime > 10.0 并触发播放逻辑
while (1) { while (1) {
// 0. 优先检查网络是否已恢复 (比如插上了网线) time_t now = time(NULL);
if (last_recovery_time == 0 ||
difftime(now, last_recovery_time) >= WIFI_OFFLINE_RECOVERY_INTERVAL_SEC) {
/* 从本轮开始计时,保证两轮检测启动时间约间隔 40 秒。 */
last_recovery_time = now;
if (has_internet_connection()) { if (has_internet_connection()) {
my_zlog_info("检测到网络已恢复,退出扫码模式。"); my_zlog_info("检测到网络已恢复,退出扫码模式。");
prepare_offline_audio_after_network(); prepare_offline_audio_after_network();
play_audio_file("connectionSuccessful.mp3"); play_audio_file("connectionSuccessful.mp3");
break; break;
} }
if (run_offline_recovery_cycle())
// 1. 周期性播放提示音 (每 10 秒) break;
time_t now = time(NULL);
if (difftime(now, last_prompt_time) >= 10.0) {
// 再检查一次,如果有网就不播了,避免干扰
if (!has_internet_connection()) {
play_audio_file("toScanQRCode.mp3");
}
last_prompt_time = now;
} }
// 2. 调用 fswebcam 拍照 // 2. 调用 fswebcam 拍照
...@@ -532,8 +563,13 @@ void check_and_autoconfig_wifi() { ...@@ -532,8 +563,13 @@ void check_and_autoconfig_wifi() {
if (cap_ret != 0) { if (cap_ret != 0) {
// 拍照失败,通常意味着没插摄像头或设备忙 // 拍照失败,通常意味着没插摄像头或设备忙
my_zlog_error("摄像头拍照失败 (fswebcam 返回 %d),请检查设备连接。", cap_ret); my_zlog_error("摄像头拍照失败 (fswebcam 返回 %d),请检查设备连接。", cap_ret);
now = time(NULL);
if (last_camera_warning_time == 0 ||
difftime(now, last_camera_warning_time) >= WIFI_OFFLINE_RECOVERY_INTERVAL_SEC) {
play_audio_file("noCameraDetected.mp3"); play_audio_file("noCameraDetected.mp3");
sleep(10); // 失败后多睡一会儿 last_camera_warning_time = now;
}
sleep(5);
continue; continue;
} }
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
// 启动断网自动配网流程 // 启动断网自动配网流程
void check_and_autoconfig_wifi(); void check_and_autoconfig_wifi();
// 运行期断网守护:每 40 秒播报、扫描并尝试连接已保存 WiFi
void *thread_wifi_offline_recovery(void *arg);
// 启动时加载离线语言配置(默认中文) // 启动时加载离线语言配置(默认中文)
void audio_init_offline_language(void); void audio_init_offline_language(void);
......
No preview for this file type
This diff is collapsed.
#ifndef AUDIOPLAY_H__
#define AUDIOPLAY_H__
#include <cjson/cJSON.h>
void audioplay_mqtt_receive(cJSON *body); //接收音频mqtt播放函数
void audioplay_local_mqtt_receive(cJSON *body); // 2017 有人驾驶本地音频
void audioplay_cycle();//音频播放线程中函数
int audio_wheat_init();
int audio_speaker_init();
int audio_init();
int audio_config_init();//加入配置
#endif
\ No newline at end of file
...@@ -9,4 +9,4 @@ file perms = 600 ...@@ -9,4 +9,4 @@ file perms = 600
millisecond = "%d(%Y-%m-%d %H:%M:%S).%ms [%V] %m%n" millisecond = "%d(%Y-%m-%d %H:%M:%S).%ms [%V] %m%n"
[rules] [rules]
my_log.* "/home/orangepi/car/master/log/log_2026-07-14.log"; millisecond my_log.* "/home/orangepi/car/master/log/log_2026-07-20.log"; millisecond
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment