fix(elecraft): the K3 power meter converts to real watts

The operator measured the whole table: 10 W showed 83, 12 W showed 100, 13 W
showed 8 — the bargraph is relative to a meter RANGE that flips at 12 W
(0-12 QRP, 0-120 above). A bar percentage was never watts; with the PC
setting choosing the range, it converts, and the console prints the watts
beside the bar.
This commit is contained in:
2026-08-30 13:31:34 +02:00
parent 37298afd77
commit 0b909a4d63
4 changed files with 26 additions and 7 deletions
+4 -2
View File
@@ -3,10 +3,12 @@
"version": "0.27.2", "version": "0.27.2",
"date": "", "date": "",
"en": [ "en": [
"Bulk operations work on any size of selection — setting a field, fixing frequencies, deleting, marking uploads and exporting the selection all failed with “too many SQL variables” past a few tens of thousands of QSOs. Statements are now issued in slices." "Bulk operations work on any size of selection — setting a field, fixing frequencies, deleting, marking uploads and exporting the selection all failed with “too many SQL variables” past a few tens of thousands of QSOs. Statements are now issued in slices.",
"Elecraft console: the power meter reads in real watts. The K3s bargraph is relative to a range that flips at 12 W — calibrated against a real radios full table, the PC setting picks the range and the bar converts to watts."
], ],
"fr": [ "fr": [
"Les opérations groupées fonctionnent quelle que soit la taille de la sélection — définir un champ, corriger des fréquences, supprimer, marquer les uploads et exporter la sélection échouaient avec « too many SQL variables » au-delà de quelques dizaines de milliers de QSO. Les requêtes sont désormais émises par tranches." "Les opérations groupées fonctionnent quelle que soit la taille de la sélection — définir un champ, corriger des fréquences, supprimer, marquer les uploads et exporter la sélection échouaient avec « too many SQL variables » au-delà de quelques dizaines de milliers de QSO. Les requêtes sont désormais émises par tranches.",
"Console Elecraft : le wattmètre lit en vrais watts. Le bargraph du K3 est relatif à une gamme qui bascule à 12 W — calibré sur la table complète dune vraie radio, le réglage PC choisit la gamme et la barre se convertit en watts."
] ]
}, },
{ {
+3 -2
View File
@@ -18,7 +18,7 @@ type KenwoodState = {
available: boolean; model?: string; elecraft: boolean; mode?: string; data_sub?: string; available: boolean; model?: string; elecraft: boolean; mode?: string; data_sub?: string;
transmitting: boolean; split: boolean; split_tx_hz?: number; transmitting: boolean; split: boolean; split_tx_hz?: number;
s_meter: number; s_meter_raw: number; s_meter: number; s_meter_raw: number;
power_meter: number; swr: number; swr_raw: number; power_meter: number; power_w?: number; swr: number; swr_raw: number;
rf_power: number; af_gain: number; rf_gain: number; mic_gain: number; squelch: number; rf_power: number; af_gain: number; rf_gain: number; mic_gain: number; squelch: number;
preamp: boolean; att: boolean; nb: boolean; nr: boolean; agc?: string; preamp: boolean; att: boolean; nb: boolean; nr: boolean; agc?: string;
filter_hz: number; antenna: number; rit: boolean; xit: boolean; rit_offset: number; key_speed: number; filter_hz: number; antenna: number; rit: boolean; xit: boolean; rit_offset: number; key_speed: number;
@@ -222,7 +222,8 @@ export function ElecraftPanel({ onReportRST }: { onReportRST?: (rst: string) =>
onReportRST(sMeterRST(sp.s, sp.over, view.mode)); onReportRST(sMeterRST(sp.s, sp.over, view.mode));
}} }}
title={t('k3.sMeterHint', { raw: String(view.s_meter_raw) })} /> title={t('k3.sMeterHint', { raw: String(view.s_meter_raw) })} />
<MeterBar label="PWR" value={view.transmitting ? view.power_meter : 0} lo={0} hi={100} accent="#0ea5e9" /> <MeterBar label="PWR" value={view.transmitting ? view.power_meter : 0} lo={0} hi={100} accent="#0ea5e9"
display={view.transmitting && view.elecraft ? `${view.power_w ?? 0} W` : undefined} />
{/* 0 means "not measured", and it must not render as a perfect 1.0: {/* 0 means "not measured", and it must not render as a perfect 1.0:
a match that looks ideal on an antenna nobody has measured is the one a match that looks ideal on an antenna nobody has measured is the one
reading that can cost a radio. */} reading that can cost a radio. */}
+2
View File
@@ -1083,6 +1083,7 @@ export namespace cat {
s_meter: number; s_meter: number;
s_meter_raw: number; s_meter_raw: number;
power_meter: number; power_meter: number;
power_w: number;
swr: number; swr: number;
swr_raw: number; swr_raw: number;
rf_power: number; rf_power: number;
@@ -1120,6 +1121,7 @@ export namespace cat {
this.s_meter = source["s_meter"]; this.s_meter = source["s_meter"];
this.s_meter_raw = source["s_meter_raw"]; this.s_meter_raw = source["s_meter_raw"];
this.power_meter = source["power_meter"]; this.power_meter = source["power_meter"];
this.power_w = source["power_w"];
this.swr = source["swr"]; this.swr = source["swr"];
this.swr_raw = source["swr_raw"]; this.swr_raw = source["swr_raw"];
this.rf_power = source["rf_power"]; this.rf_power = source["rf_power"];
+14
View File
@@ -53,6 +53,12 @@ type KenwoodTXState struct {
// PowerMeter is 0-100 while transmitting. SWR is the ratio; 0 means "not // PowerMeter is 0-100 while transmitting. SWR is the ratio; 0 means "not
// measured", NOT a perfect match. // measured", NOT a perfect match.
PowerMeter int `json:"power_meter"` PowerMeter int `json:"power_meter"`
// PowerW is the transmit power in WATTS, derived from the bargraph and the
// meter's RANGE. The K3's bar is relative to a range that flips at 12 W —
// calibrated against a real one: 10 W showed 83 (10/12), 100 W showed 83
// too (100/120). The bar alone never was watts; with the PC setting to
// pick the range, it converts. 0 while receiving.
PowerW int `json:"power_w"`
SWR float64 `json:"swr"` SWR float64 `json:"swr"`
SWRRaw int `json:"swr_raw"` SWRRaw int `json:"swr_raw"`
@@ -162,6 +168,7 @@ func (k *Kenwood) readPanel(mode string, split bool, txHz int64, txNow bool) {
// Cleared, not frozen: a power bar left standing after the carrier drops // Cleared, not frozen: a power bar left standing after the carrier drops
// reads as a live transmission. // reads as a live transmission.
k.panel.PowerMeter = 0 k.panel.PowerMeter = 0
k.panel.PowerW = 0
k.panel.SWR, k.panel.SWRRaw = 0, 0 k.panel.SWR, k.panel.SWRRaw = 0, 0
k.powerPeak, k.swrPeak = meterPeak{}, meterPeak{} k.powerPeak, k.swrPeak = meterPeak{}, meterPeak{}
// The S-meter only means anything while receiving. // The S-meter only means anything while receiving.
@@ -341,6 +348,13 @@ func (k *Kenwood) readTXMeters() {
defer func() { k.noLatch = false }() defer func() { k.noLatch = false }()
if v, ok := k.askNum("BG;", "BG", 2); ok { if v, ok := k.askNum("BG;", "BG", 2); ok {
k.panel.PowerMeter = k.powerPeak.update(kenwoodBargraphPercent(v), now) k.panel.PowerMeter = k.powerPeak.update(kenwoodBargraphPercent(v), now)
if k.elecraft {
scale := 120
if k.panel.RFPower > 0 && k.panel.RFPower <= 12 {
scale = 12 // the K3's QRP range
}
k.panel.PowerW = k.panel.PowerMeter * scale / 100
}
} }
// SW; — SETTLED, from Elecraft's own release note: three digits, tenths of a // SW; — SETTLED, from Elecraft's own release note: three digits, tenths of a
// ratio. "SW023;" is 2.3:1, and "SW999;" is the 99.9:1 it reports instead of // ratio. "SW023;" is 2.3:1, and "SW999;" is the 99.9:1 it reports instead of