diff --git a/changelog.json b/changelog.json index c820f3d..c388349 100644 --- a/changelog.json +++ b/changelog.json @@ -5,12 +5,14 @@ "en": [ "QSOs logged from WSJT-X now carry the space weather and the distance, like hand-logged ones. The UDP path stamped the station profile, the DXCC and the QSL defaults but not SFI, A, K or distance — so an operator running digital had those fields empty across the whole log. Space weather is only stamped on a contact less than a day old: a logger re-broadcasting its backlog would otherwise be handed this morning readings for last month contacts.", "Band openings: EME contacts are no longer mistaken for an opening. A 2 m opening was announced at 9650 km towards Japan on stations working moonbounce — real contacts, but the moon says nothing about the band, and an antenna pointed that way finds nothing. Each band now has the longest path the atmosphere can actually carry: 3500 km on 2 m, 4000 on 4 m, and no limit at all on 6 and 10 m where multi-hop really does go round the world.", - "Kenwood: WSJT-X \"Fake It\" no longer leaves the dial on the transmit frequency. A frequency set while transmitting was not recorded, so WSJT-X was told the radio was already back on the receive frequency and never restored it." + "Kenwood: WSJT-X \"Fake It\" no longer leaves the dial on the transmit frequency. A frequency set while transmitting was not recorded, so WSJT-X was told the radio was already back on the receive frequency and never restored it.", + "PowerGenius XL: the Station Control card now shows power, current, SWR and temperature without a FlexRadio. The meters were only ever drawn from the radio's stream, so a station on any other rig got an empty card while the amplifier was reporting all four over its own link." ], "fr": [ "Les QSO enregistrés depuis WSJT-X portent désormais la météo spatiale et la distance, comme ceux saisis à la main. Le chemin UDP posait le profil station, le DXCC et les défauts QSL mais ni SFI, ni A, ni K, ni distance — un opérateur en numérique avait donc ces champs vides sur tout son log. La météo spatiale n est posée que sur un contact de moins d un jour : sinon un logiciel qui rediffuse son historique se verrait attribuer les relevés de ce matin sur des contacts du mois dernier.", "Ouvertures de bande : les contacts EME ne sont plus pris pour une ouverture. Une ouverture 2 m était annoncée à 9650 km vers le Japon sur des stations en rebond lunaire — de vrais contacts, mais la Lune ne dit rien de la bande, et une antenne pointée par là ne trouve rien. Chaque bande a désormais la distance maximale que l atmosphère peut réellement porter : 3500 km en 2 m, 4000 en 4 m, et aucune limite en 6 et 10 m où les sauts multiples font vraiment le tour du monde.", - "Kenwood : le « Fake It » de WSJT-X ne laisse plus le VFO sur la fréquence d émission. Un changement de fréquence pendant l émission n était pas enregistré, WSJT-X croyait donc la radio déjà revenue sur la fréquence de réception et ne la remettait jamais en place." + "Kenwood : le « Fake It » de WSJT-X ne laisse plus le VFO sur la fréquence d émission. Un changement de fréquence pendant l émission n était pas enregistré, WSJT-X croyait donc la radio déjà revenue sur la fréquence de réception et ne la remettait jamais en place.", + "PowerGenius XL : la carte du Contrôle station affiche désormais puissance, courant, ROS et température sans FlexRadio. Les mesures n étaient tirées que du flux de la radio, si bien qu une station sur une autre radio n avait qu une carte vide alors que l amplificateur remontait les quatre sur sa propre liaison." ] }, { diff --git a/frontend/src/components/AmpCard.tsx b/frontend/src/components/AmpCard.tsx index adbb75c..7ffc985 100644 --- a/frontend/src/components/AmpCard.tsx +++ b/frontend/src/components/AmpCard.tsx @@ -174,6 +174,41 @@ export function AmpCard({ amp, flex, t }: { amp: Amp; flex: any; t: (k: string, const operate = viaFlex ? !!flex?.amp_operate : !!pg.operate; const connected = !!pg.connected || viaFlex; const fault = flex?.amp_fault; + + // Meters built from the amplifier's own GSCP status frame, for when the radio + // is not feeding a meter stream. + // + // Whether there is power is the amp's state field; how much is the plain + // forward figure. NOT "peakfwd" — that is a latched maximum which is never + // reset and survives in the last-known status after the amp disconnects, so it + // once claimed 1350 W from an old transmission while 10 W was going out. Same + // reason peak_id is left alone. Both readings are gated on transmit so they + // fall back to zero between overs instead of freezing on the last one. + const pgxlMeters = () => { + if (!pg.connected) return null; + const txing = typeof flex?.transmitting === 'boolean' ? flex.transmitting : /TRANSMIT/i.test(pg.state || ''); + const fwdW = peakHold('pgfwd', txing ? Number(pg.fwd_w) || 0 : 0); + const idA = peakHold('pgid', txing ? Number(pg.id) || 0 : 0); + const swr = peakHold('pgswr', txing ? Number(pg.vswr) || 0 : 0); + const tempC = Number(pg.temperature) || 0; + return ( +
+ (f > 0.9 ? '#dc2626' : f > 0.75 ? '#f59e0b' : '#ea580c')} /> + + {/* Below 1:1 the reading is meaningless, so an idle amp shows a flat bar + rather than a zero that looks like a perfect match. */} + = 1 ? swr : 1} lo={1} hi={3} + display={swr >= 1 ? swr.toFixed(1) : '—'} + segColor={(f) => (f > 0.75 ? '#dc2626' : f > 0.4 ? '#f59e0b' : '#16a34a')} /> + 0 ? `${Math.round(tempC)} °C` : '—'} + segColor={(f) => (f > 0.8 ? '#dc2626' : f > 0.6 ? '#f59e0b' : '#ea580c')} /> +
+ ); + }; + return (
@@ -204,13 +239,20 @@ export function AmpCard({ amp, flex, t }: { amp: Amp; flex: any; t: (k: string, {t('flxp.fault')}: {fault} )}
- {/* Amplifier meters (FWD / ID / TEMP …) from the FlexRadio UDP stream. */} - {viaFlex && (() => { + {/* Amplifier meters (FWD / ID / TEMP …). + The FlexRadio UDP stream is the preferred source — it is fast and reads + the same as SmartSDR. When there is no Flex, or it is not streaming, + the amplifier's OWN link carries the same figures; falling back to them + is what the docked widget already does. Without that fallback this card + showed an operator on a Kenwood nothing but OPERATE and the fan mode, + while the amplifier was reporting power, current and temperature all + along. */} + {(() => { const meters = (flex?.meters as any[]) || []; const dbmToW = (d: number) => Math.pow(10, (d - 30) / 10); const amps = meters.filter((m) => (m.src || '').toUpperCase().includes('AMP') && !/^(RL|DRV)$/i.test((m.name || '').trim())); - if (amps.length === 0) return null; + if (!viaFlex || amps.length === 0) return pgxlMeters(); // Power comes from the radio's meter stream and nothing else. The // amplifier also reports a "peakfwd", and using it was a mistake twice // over: it is a latched maximum that is never reset, and it survives in