diff --git a/changelog.json b/changelog.json
index c5973ef..011d1bb 100644
--- a/changelog.json
+++ b/changelog.json
@@ -3,10 +3,12 @@
"version": "0.27.2",
"date": "",
"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 K3’s bargraph is relative to a range that flips at 12 W — calibrated against a real radio’s full table, the PC setting picks the range and the bar converts to watts."
],
"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 d’une vraie radio, le réglage PC choisit la gamme et la barre se convertit en watts."
]
},
{
diff --git a/frontend/src/components/ElecraftPanel.tsx b/frontend/src/components/ElecraftPanel.tsx
index 0908c7e..2774a61 100644
--- a/frontend/src/components/ElecraftPanel.tsx
+++ b/frontend/src/components/ElecraftPanel.tsx
@@ -18,7 +18,7 @@ type KenwoodState = {
available: boolean; model?: string; elecraft: boolean; mode?: string; data_sub?: string;
transmitting: boolean; split: boolean; split_tx_hz?: 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;
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;
@@ -222,7 +222,8 @@ export function ElecraftPanel({ onReportRST }: { onReportRST?: (rst: string) =>
onReportRST(sMeterRST(sp.s, sp.over, view.mode));
}}
title={t('k3.sMeterHint', { raw: String(view.s_meter_raw) })} />
-
+
{/* 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
reading that can cost a radio. */}
diff --git a/frontend/wailsjs/go/models.ts b/frontend/wailsjs/go/models.ts
index 80d7964..3ef7003 100644
--- a/frontend/wailsjs/go/models.ts
+++ b/frontend/wailsjs/go/models.ts
@@ -1083,6 +1083,7 @@ export namespace cat {
s_meter: number;
s_meter_raw: number;
power_meter: number;
+ power_w: number;
swr: number;
swr_raw: number;
rf_power: number;
@@ -1120,6 +1121,7 @@ export namespace cat {
this.s_meter = source["s_meter"];
this.s_meter_raw = source["s_meter_raw"];
this.power_meter = source["power_meter"];
+ this.power_w = source["power_w"];
this.swr = source["swr"];
this.swr_raw = source["swr_raw"];
this.rf_power = source["rf_power"];
diff --git a/internal/cat/kenwood_panel.go b/internal/cat/kenwood_panel.go
index 72657f2..d032de8 100644
--- a/internal/cat/kenwood_panel.go
+++ b/internal/cat/kenwood_panel.go
@@ -52,9 +52,15 @@ type KenwoodTXState struct {
SMeterRaw int `json:"s_meter_raw"`
// PowerMeter is 0-100 while transmitting. SWR is the ratio; 0 means "not
// measured", NOT a perfect match.
- PowerMeter int `json:"power_meter"`
- SWR float64 `json:"swr"`
- SWRRaw int `json:"swr_raw"`
+ 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"`
+ SWRRaw int `json:"swr_raw"`
RFPower int `json:"rf_power"` // watts, the PC setting
AFGain int `json:"af_gain"` // 0-100
@@ -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
// reads as a live transmission.
k.panel.PowerMeter = 0
+ k.panel.PowerW = 0
k.panel.SWR, k.panel.SWRRaw = 0, 0
k.powerPeak, k.swrPeak = meterPeak{}, meterPeak{}
// The S-meter only means anything while receiving.
@@ -341,6 +348,13 @@ func (k *Kenwood) readTXMeters() {
defer func() { k.noLatch = false }()
if v, ok := k.askNum("BG;", "BG", 2); ok {
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
// ratio. "SW023;" is 2.3:1, and "SW999;" is the 99.9:1 it reports instead of