fix BLE wifi status delivery and websocket compile issues

This commit is contained in:
showen
2026-03-12 08:07:21 +08:00
parent 7548064401
commit 8ed9c93c8e
10 changed files with 886 additions and 49 deletions

View File

@@ -6,10 +6,29 @@ mod routes;
use crate::core::config::AppConfig;
use crate::core::message::{Envelope, Message};
use crate::core::plugin::{Plugin, PluginContext, PluginInfo, Platform};
use crate::core::plugin::{Platform, Plugin, PluginContext, PluginInfo};
use anyhow::{Context, Result};
use serde::Serialize;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Condvar, Mutex};
use tokio::sync::broadcast;
#[derive(Serialize)]
struct WsEvent<'a, T> {
#[serde(rename = "type")]
event_type: &'a str,
data: T,
}
fn encode_ws_event<T: Serialize>(event_type: &str, data: T) -> Option<String> {
match serde_json::to_string(&WsEvent { event_type, data }) {
Ok(payload) => Some(payload),
Err(error) => {
eprintln!("[HttpPlugin] failed to serialize websocket event '{event_type}': {error}");
None
}
}
}
struct PendingWifiResponse {
version: u64,
@@ -22,10 +41,12 @@ pub(crate) struct HttpState {
config: Mutex<Arc<AppConfig>>,
player_status: Mutex<crate::core::message::PlayerStatusData>,
ble_ready: AtomicBool,
ws_events: broadcast::Sender<String>,
}
impl HttpState {
fn new(config: Arc<AppConfig>) -> Self {
let (ws_events, _) = broadcast::channel(32);
let player_status = crate::core::message::PlayerStatusData {
running: false,
paused: !config.playback.auto_start,
@@ -44,6 +65,7 @@ impl HttpState {
config: Mutex::new(config),
player_status: Mutex::new(player_status),
ble_ready: AtomicBool::new(false),
ws_events,
}
}
@@ -92,8 +114,42 @@ impl HttpState {
self.ble_ready.load(Ordering::SeqCst)
}
fn publish_ws(&self, payload: String) {
let _ = self.ws_events.send(payload);
}
pub(crate) fn ws_snapshots(&self) -> Vec<String> {
let mut snapshots = Vec::new();
if let Some(payload) = encode_ws_event("status_update", self.player_status()) {
snapshots.push(payload);
}
let config = self.config();
if let Some(payload) = encode_ws_event("config_update", config.as_ref()) {
snapshots.push(payload);
}
if let Some(payload) = encode_ws_event(
"ble_update",
serde_json::json!({ "ready": self.ble_ready() }),
) {
snapshots.push(payload);
}
snapshots
}
pub(crate) fn ws_subscribe(&self) -> broadcast::Receiver<String> {
self.ws_events.subscribe()
}
fn set_ble_ready(&self, ready: bool) {
self.ble_ready.store(ready, Ordering::SeqCst);
if let Some(payload) = encode_ws_event("ble_update", serde_json::json!({ "ready": ready }))
{
self.publish_ws(payload);
}
}
}
@@ -118,7 +174,9 @@ impl Default for HttpPlugin {
}
impl Plugin for HttpPlugin {
fn id(&self) -> &'static str { "http" }
fn id(&self) -> &'static str {
"http"
}
fn info(&self) -> PluginInfo {
PluginInfo {
@@ -129,6 +187,10 @@ impl Plugin for HttpPlugin {
}
}
fn dependencies(&self) -> Vec<&'static str> {
vec!["video"]
}
fn init(&mut self, ctx: PluginContext) -> Result<()> {
self.state = Some(Arc::new(HttpState::new(Arc::clone(&ctx.config))));
self.ctx = Some(ctx);
@@ -201,8 +263,29 @@ impl Plugin for HttpPlugin {
match msg {
Message::WifiResult(payload) => state.publish_wifi_result(payload),
Message::PlayerStatus(status) => state.update_player_status(status),
Message::ConfigReloaded(config) => state.replace_config(config),
Message::PlayerStatus(status) => {
state.update_player_status(status.clone());
if let Some(payload) = encode_ws_event("status_update", &status) {
state.publish_ws(payload);
}
}
Message::ConfigReloaded(config) => {
state.replace_config(Arc::clone(&config));
if let Some(payload) = encode_ws_event("config_update", config.as_ref()) {
state.publish_ws(payload);
}
}
Message::StateChanged {
old_state,
new_state,
} => {
if let Some(payload) = encode_ws_event(
"state_update",
serde_json::json!({ "old_state": old_state, "new_state": new_state }),
) {
state.publish_ws(payload);
}
}
Message::PluginReady("ble") => state.set_ble_ready(true),
Message::Shutdown => state.set_ble_ready(false),
_ => {}
@@ -211,5 +294,7 @@ impl Plugin for HttpPlugin {
Ok(())
}
fn stop(&mut self) -> Result<()> { Ok(()) }
fn stop(&mut self) -> Result<()> {
Ok(())
}
}