diff --git a/changelog.json b/changelog.json index fa43548..82a5cf4 100644 --- a/changelog.json +++ b/changelog.json @@ -10,7 +10,8 @@ "Fixed OpsLog re-tuning its own rig from its own radio broadcasts, which dropped the CAT link on every JTDX or WSJT-X “Fake It” transmission.", "New device: a bench power supply on Modbus RTU (BSIDE, Wanptek and kin) — its output switched from Station Control, with volts, amps and watts.", "SPID rotator: a Rot1Prog controller turned nearly a full circle the wrong way for every heading — its commands take three digits, not four.", - "The compass now follows a turning antenna smoothly, and a rotator test that only reads the heading says so instead of naming PstRotator." + "The compass sweeps with a turning antenna instead of jumping, and the controller is polled once for the whole app rather than by each panel.", + "A rotator test that only reads the heading now says so, instead of naming PstRotator for a move it never commanded." ], "fr": [ "Clic droit : mettre à jour le comté US des contacts sélectionnés depuis la base ULS, pour remplacer un comté renommé ou supprimé.", @@ -20,7 +21,8 @@ "Corrigé : OpsLog réaccordait sa propre radio depuis ses propres diffusions, ce qui coupait le lien CAT à chaque émission JTDX ou WSJT-X en « Fake It ».", "Nouvel appareil : alimentation de laboratoire en Modbus RTU (BSIDE, Wanptek et similaires) — sortie commutée depuis Contrôle station, avec V, A et W.", "Rotator SPID : un contrôleur Rot1Prog tournait presque un tour complet à l’envers pour chaque azimut — ses commandes tiennent trois chiffres, pas quatre.", - "Le compas suit désormais une antenne en rotation sans à-coups, et un test de rotator qui ne fait que lire l’azimut le dit au lieu de citer PstRotator." + "Le compas suit l’antenne en rotation au lieu de sauter, et le contrôleur est interrogé une fois pour toute l’application, plus par chaque panneau.", + "Un test de rotator qui ne fait que lire l’azimut le dit, au lieu de citer PstRotator pour un mouvement jamais commandé." ] }, { diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 8179595..18144be 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -21,7 +21,7 @@ import { GetCATState, SetCATFrequency, SetCATMode, SwitchCATRig, EntryBandChanged, FlexApplyBandAntenna, FlexApplyBandPower, GetSecretStatus, UnlockSecrets, RefreshCtyDat, DownloadAllReferenceLists, - RotatorGoTo, RotatorStop, GetRotatorHeading, SetActiveRotor, + RotatorGoTo, RotatorStop, SetActiveRotor, GetDBConnectionInfo, GetLogbookRevision, GetUltrabeamStatus, SetUltrabeamDirection, UILog, GetAntGeniusStatus, GetAntGeniusSettings, AntGeniusActivate, @@ -107,6 +107,7 @@ import { DetailsPanel, type DetailsState } from '@/components/DetailsPanel'; import { SendSpotModal, type RecentSpotQSO } from '@/components/SendSpotModal'; import { WinkeyerPanel, type WKStatus, type WKMacro } from '@/components/WinkeyerPanel'; import { RotorCompass } from '@/components/RotorCompass'; +import { subscribeRotorHeading, pokeRotorHeading } from '@/lib/rotorHeading'; import { writeUiPref } from '@/lib/uiPref'; import { formatDateTimeUTC } from '@/lib/dateFormat'; import { titleCase, sentenceCase } from '@/lib/textCase'; @@ -2390,22 +2391,12 @@ export default function App() { }; }, []); - // Poll the rotator for the live antenna heading (status bar and compass). - // Cheap when it is disabled — the backend just reads settings and returns. - // - // 700 ms, not three seconds: a turning antenna moved the needle in steps of - // about thirteen degrees, which reads as a compass that jumps rather than one - // that sweeps. A heading query is a few bytes on a serial controller or one - // short exchange over TCP. - useEffect(() => { - let alive = true; - const tick = async () => { - try { const h: any = await GetRotatorHeading(); if (alive) setRotatorHeading(h); } catch {} - }; - tick(); - const id = window.setInterval(tick, 700); - return () => { alive = false; window.clearInterval(id); }; - }, []); + // The live antenna heading, from the shared poller in lib/rotorHeading — fast + // while the antenna turns, slow while it is parked, and ONE loop however many + // panels are watching. This used to be its own interval alongside Station + // Control's, so the controller was polled twice over whenever that tab was + // open, and every poll opens and closes the port. + useEffect(() => subscribeRotorHeading((h) => setRotatorHeading(h as any)), []); // Poll the Ultrabeam antenna for its connection + pattern direction. useEffect(() => { @@ -5496,7 +5487,7 @@ export default function App() {