style(icom): the shared LED meters, and the sideband named
The console's thin home-made bars were the one holdout — every other panel (Flex, Elecraft, the amps, the tuner) draws the same MeterBar. And the mode badge said SSB, which on any band leaves the operator guessing which sideband the rig is on: the panel now shows USB or LSB (the log keeps ADIF's SSB).
This commit is contained in:
+4
-2
@@ -33,7 +33,8 @@
|
||||
"Icom console: the spectrum scope is removed. Every model streams its waveform differently — and on the IC-7760 enabling it killed the whole CI-V link, audio included. The radio’s own scope does it better.",
|
||||
"Icom: any leftover waveform stream is switched off at connect — the scope flag lives in the radio and survived sessions, and its flood is what was killing the IC-7760’s CI-V link.",
|
||||
"Icom console: an ATU chip beside SPLIT engages or DISENGAGES the internal tuner — TUNE started a cycle but could never take the tuner back out of line.",
|
||||
"Icom console: the TX meters get needle inertia — power holds its peak instead of flickering to 0 W between syllables, SWR shows the real peak then returns to the live value — and the wattage readout no longer wraps at three digits."
|
||||
"Icom console: the TX meters get needle inertia — power holds its peak instead of flickering to 0 W between syllables, SWR shows the real peak then returns to the live value — and the wattage readout no longer wraps at three digits.",
|
||||
"Icom console: the meters use the same LED bars as the Flex and Elecraft consoles, and the mode badge says USB or LSB instead of an ambiguous SSB."
|
||||
],
|
||||
"fr": [
|
||||
"Console Elecraft : le S-mètre est calibré sur un vrai K3 — S9 et les +dB correspondent désormais à l’affichage de la radio (il lisait environ deux points S trop bas).",
|
||||
@@ -66,7 +67,8 @@
|
||||
"Console Icom : le scope spectral est retiré. Chaque modèle streame sa forme d’onde différemment — et sur l’IC-7760 son activation tuait tout le lien CI-V, audio compris. Le scope de la radio fait ça mieux.",
|
||||
"Icom : tout flux waveform résiduel est coupé à la connexion — le drapeau scope vit dans la radio et survivait aux sessions, et son flot est ce qui tuait le lien CI-V de l’IC-7760.",
|
||||
"Console Icom : une puce ATU à côté de SPLIT engage ou DÉSENGAGE le tuner interne — TUNE lançait un cycle mais ne pouvait jamais remettre le tuner hors ligne.",
|
||||
"Console Icom : les mètres TX gagnent une inertie d’aiguille — la puissance tient sa crête au lieu de retomber à 0 W entre les syllabes, le ROS montre la vraie crête puis revient à la valeur vive — et l’affichage en watts ne passe plus à la ligne à trois chiffres."
|
||||
"Console Icom : les mètres TX gagnent une inertie d’aiguille — la puissance tient sa crête au lieu de retomber à 0 W entre les syllabes, le ROS montre la vraie crête puis revient à la valeur vive — et l’affichage en watts ne passe plus à la ligne à trois chiffres.",
|
||||
"Console Icom : les mètres utilisent les mêmes barres LED que les consoles Flex et Elecraft, et le badge de mode dit USB ou LSB au lieu d’un SSB ambigu."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -284,6 +284,13 @@ function Meter({ label, value, accent, scale, onClick, title }: { label: string;
|
||||
// sParts turns the raw 0-100 S-meter into S-unit + dB-over-S9 (S9 ≈ 47% on the
|
||||
// CI-V 0-255 scale, +60 dB near full scale). Used for both the display label and
|
||||
// the RST-tx value on click.
|
||||
// Green to S9, amber through +20, red above — the Elecraft console's scale.
|
||||
function sSegColor(frac: number) {
|
||||
if (frac > 0.78) return '#dc2626';
|
||||
if (frac > 0.55) return '#f59e0b';
|
||||
return '#16a34a';
|
||||
}
|
||||
|
||||
function sParts(v: number): { s: number; over: number; label: string } {
|
||||
if (v >= 47) {
|
||||
const over = Math.max(0, Math.round((v - 47) * 60 / 47));
|
||||
@@ -420,7 +427,9 @@ export function IcomPanel({ onReportRST, isNetwork = false }: { onReportRST?: (r
|
||||
// in split the CAT state's TX freq is the authority, otherwise the panel's
|
||||
// own sub_hz read.
|
||||
const subHz: number = split ? (cat?.freq_hz || 0) : (st.sub_hz || 0);
|
||||
const curMode: string = cat?.mode || st.mode || '';
|
||||
// The panel's own mode first: it carries the sideband (USB/LSB) where the
|
||||
// CAT state folds both into ADIF's SSB.
|
||||
const curMode: string = st.mode || cat?.mode || '';
|
||||
// Mode-dependent controls: VOX / speech-comp / mic are voice-only (hidden on
|
||||
// CW and data); APF (audio peak filter) is CW-only. Fold USB/LSB into phone.
|
||||
const um = curMode.toUpperCase();
|
||||
@@ -512,21 +521,26 @@ export function IcomPanel({ onReportRST, isNetwork = false }: { onReportRST?: (r
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Live meters — always visible: S (RX, click → RST), Po in watts, SWR. */}
|
||||
<div className="rounded-xl border border-border bg-card px-3 py-2.5 shadow-sm grid grid-cols-1 sm:grid-cols-3 gap-x-5 gap-y-2">
|
||||
{/* Live meters — the SAME LED MeterBar every other console uses (Flex,
|
||||
Elecraft, the amp cards): one instrument look across the app, per the
|
||||
operator's "les consoles doivent se ressembler". S is clickable → RST. */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-2">
|
||||
{(() => { const sp = sParts(st.s_meter); return (
|
||||
<Meter label="S" value={st.s_meter} accent="#22c55e" scale={sp.label}
|
||||
<MeterBar label="S-METER" value={st.transmitting ? 0 : st.s_meter} lo={0} hi={100}
|
||||
accent="#16a34a" segColor={sSegColor}
|
||||
display={st.transmitting ? '—' : sp.label}
|
||||
title={onReportRST ? t('rst.clickToFill') : undefined}
|
||||
onClick={onReportRST ? () => onReportRST(sMeterRST(sp.s, sp.over, st.mode)) : undefined} />
|
||||
onClick={onReportRST ? () => { if (!st.transmitting) onReportRST(sMeterRST(sp.s, sp.over, st.mode)); } : undefined} />
|
||||
); })()}
|
||||
{(() => {
|
||||
if ((st.model ?? '').includes('7760')) {
|
||||
const { w, defl } = icomWatts(st.power_meter);
|
||||
return <Meter label="Po" value={defl} accent="#ef4444" scale={`${w} W`} />;
|
||||
return <MeterBar label="PWR" value={defl} lo={0} hi={100} accent="#0ea5e9" display={`${w} W`} />;
|
||||
}
|
||||
return <Meter label="Po" value={st.power_meter} accent="#ef4444" scale={`${st.power_meter} W`} />;
|
||||
return <MeterBar label="PWR" value={st.power_meter} lo={0} hi={100} accent="#0ea5e9" display={`${st.power_meter} W`} />;
|
||||
})()}
|
||||
<Meter label="SWR" value={st.swr_meter} accent="#f59e0b" scale={st.swr_meter > 0 ? `${(1 + st.swr_meter / 33.3).toFixed(1)}` : '1.0'} />
|
||||
<MeterBar label="SWR" value={st.swr_meter > 0 ? 1 + st.swr_meter / 33.3 : 0} lo={1} hi={4} accent="#f59e0b"
|
||||
display={st.swr_meter > 0 ? (1 + st.swr_meter / 33.3).toFixed(1) : '—'} />
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-3">
|
||||
|
||||
@@ -422,6 +422,19 @@ func (b *IcomSerial) ReadState() (RigState, error) {
|
||||
}
|
||||
b.dspMu.Lock()
|
||||
b.dsp.Mode = s.Mode
|
||||
// The console says which SIDEBAND, not the ADIF family: "SSB" on 40 m
|
||||
// leaves the operator guessing whether the rig is where convention puts
|
||||
// it. The log keeps SSB; the panel shows what the radio is actually doing.
|
||||
switch b.curModeByte {
|
||||
case civ.ModeUSB:
|
||||
if s.Mode == "SSB" {
|
||||
b.dsp.Mode = "USB"
|
||||
}
|
||||
case civ.ModeLSB:
|
||||
if s.Mode == "SSB" {
|
||||
b.dsp.Mode = "LSB"
|
||||
}
|
||||
}
|
||||
b.dspMu.Unlock()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user