feat(rotator): drive a Rotator Genius through the overlap

An operator with a 450° mast watched the Genius stop at 359 and had to press
"clockwise" by hand to get through north. Half of that was ours: GoTo clamped
every target to 360 before sending it, although the wire command carries three
digits and always could have said 370.

So the clamp goes to 450, the rotator-range setting is offered for the Rotator
Genius like the other backends it applies to, and when a bearing can be reached
two ways the nearer one is taken — 010° sent as 370° when the antenna is already
at 350°, which is the entire point of having an overlap.

THE GENIUS DECIDES WHAT IS REACHABLE. It reports the limits it is configured
with, and they are the truth about what is bolted to the tower. This particular
station's box says "5 to 4" — the factory 360° range — and would refuse 370,
turning a working command into a rejected one. So the overlap is used only when
the Genius itself says it has one, and when OpsLog is set to 450 while the Genius
is not, the log says so once a minute and names the dialog to change: the setting
lives in the Genius's own Rotator Configuration, and nothing here can reach past
its limits.

The |h reply always carried those limits and they were being skipped over.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
2026-09-09 23:46:04 +02:00
co-authored by Claude Opus 5
parent b8491f3038
commit 3dad00f8ad
4 changed files with 112 additions and 10 deletions
+6 -1
View File
@@ -5135,7 +5135,12 @@ function SettingsModalImpl({ onClose, onSaved, initialSection, onMainPaneChanged
// controller. PstRotator knows which machine is on the other end and
// does its own overlap; two programs each deciding to go the long
// way round is how an antenna unwinds mid-pass.
const ownsOverlap = isERC || isEasycomm;
//
// A Rotator Genius is in between: it has its OWN limits, and they
// win — this setting only tells OpsLog it may ask for the far side
// of the overlap at all. If the Genius is configured 360°, it says
// so in the log rather than sending commands the box refuses.
const ownsOverlap = isERC || isEasycomm || isRG;
return (
<div key={dev.id || i} className="rounded-xl border border-border bg-card/40 p-3 space-y-3">
<div className="flex items-center gap-2">