[feat](trx-server): run fast S-meter tick on CAT rigs too
Extend the between-poll meter refresh that was previously SDR-only to also run on CAT backends. CAT rigs now poll the S-meter every 150 ms (SDR remains at 100 ms), so the frontend bar moves in near real-time instead of updating only on the 500 ms full-state poll. The fast path calls get_signal_strength_db() first (SDR), then falls back to the coarse get_signal_strength() + map_signal_strength path for CAT rigs. It is skipped while powered off, transmitting, or while a full poll is paused after a CAT write. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -254,17 +254,18 @@ pub async fn run_rig_task(
|
|||||||
);
|
);
|
||||||
let _ = state_tx.send(state.clone());
|
let _ = state_tx.send(state.clone());
|
||||||
|
|
||||||
// SDR backends can refresh signal strength cheaply (cached DSP value),
|
// Run a fast meter tick between full polls to keep the S-meter
|
||||||
// so we run a fast meter tick between full polls to keep the S-meter
|
// responsive. SDR backends expose a cached DSP reading and can
|
||||||
// responsive — matching the spectrum redraw rate (~100 ms).
|
// refresh every 100 ms; CAT rigs poll the serial link, which is
|
||||||
|
// slower but still fine at ~150 ms.
|
||||||
let is_sdr = rig.as_sdr_ref().is_some();
|
let is_sdr = rig.as_sdr_ref().is_some();
|
||||||
let meter_tick_duration = Duration::from_millis(100);
|
let meter_tick_duration = if is_sdr {
|
||||||
let mut meter_tick: std::pin::Pin<Box<tokio::time::Sleep>> = if is_sdr {
|
Duration::from_millis(100)
|
||||||
Box::pin(tokio::time::sleep(meter_tick_duration))
|
|
||||||
} else {
|
} else {
|
||||||
// Park indefinitely for non-SDR backends; the branch will never fire.
|
Duration::from_millis(150)
|
||||||
Box::pin(tokio::time::sleep(Duration::from_secs(86400)))
|
|
||||||
};
|
};
|
||||||
|
let mut meter_tick: std::pin::Pin<Box<tokio::time::Sleep>> =
|
||||||
|
Box::pin(tokio::time::sleep(meter_tick_duration));
|
||||||
|
|
||||||
// Main task loop
|
// Main task loop
|
||||||
let mut current_poll_duration = polling.interval(state.status.tx_en);
|
let mut current_poll_duration = polling.interval(state.status.tx_en);
|
||||||
@@ -289,11 +290,24 @@ pub async fn run_rig_task(
|
|||||||
Err(_) => break,
|
Err(_) => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Fast meter-only refresh for SDR backends (cheap cached read).
|
// Fast meter-only refresh between full polls.
|
||||||
_ = &mut meter_tick, if is_sdr => {
|
_ = &mut meter_tick => {
|
||||||
meter_tick = Box::pin(tokio::time::sleep(meter_tick_duration));
|
meter_tick = Box::pin(tokio::time::sleep(meter_tick_duration));
|
||||||
if !matches!(state.control.enabled, Some(false)) {
|
// Skip while powered off, transmitting, or while a
|
||||||
if let Some(db) = rig.get_signal_strength_db().await {
|
// full poll is paused (typically just after a CAT write).
|
||||||
|
let powered_off = matches!(state.control.enabled, Some(false));
|
||||||
|
let paused = poll_pause_until
|
||||||
|
.map(|u| Instant::now() < u)
|
||||||
|
.unwrap_or(false);
|
||||||
|
if !powered_off && !state.status.tx_en && !paused {
|
||||||
|
let new_sig = if let Some(db) = rig.get_signal_strength_db().await {
|
||||||
|
Some(db)
|
||||||
|
} else if let Ok(meter) = rig.get_signal_strength().await {
|
||||||
|
Some(map_signal_strength(&state.status.mode, meter))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
if let Some(db) = new_sig {
|
||||||
let prev = state.status.rx.as_ref().and_then(|r| r.sig);
|
let prev = state.status.rx.as_ref().and_then(|r| r.sig);
|
||||||
if prev != Some(db) {
|
if prev != Some(db) {
|
||||||
state.status.rx.get_or_insert(RigRxStatus { sig: None }).sig = Some(db);
|
state.status.rx.get_or_insert(RigRxStatus { sig: None }).sig = Some(db);
|
||||||
|
|||||||
Reference in New Issue
Block a user