feat(amp): command linked amplifiers together for a combiner
The SPE CO1-2 combiner is an RF device: it sums two amplifiers and commands nothing. So "combined" operation is really two amplifiers that must be held in the same state, and one left in STANDBY while the other keys means the combiner sees power on a single input. A switch in Settings → Amplifier makes ON, OFF and OPERATE act on every configured amplifier. Offered only with two or more: coupling one amplifier to itself is a switch that cannot do anything. The METERS stay per amplifier, deliberately. Two amps combined are still two amps, and an operator watching for one of them to run away needs to see them apart — a summed bar would hide exactly the fault worth catching. Fanned out in AmpOperate/AmpPower rather than in the UI: the card and the docked widget both call these, and a coupling built into one would be missing from the other, which on a combiner means one amplifier keyed and one not. The clicked amplifier goes first, so a partial failure still did what the operator asked before it stopped. While linked, an amplifier with no power command — a PGXL on its direct link — is skipped silently rather than reported: it would make a successful pair look broken.
This commit is contained in:
@@ -0,0 +1,36 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sort"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A combiner sums two amplifiers and commands nothing, so "combined" operation
|
||||||
|
// is really two amplifiers that must be kept in the same state. Leaving one in
|
||||||
|
// OPERATE while the other sits in STANDBY is exactly what must not happen —
|
||||||
|
// the combiner would then see power on one input only.
|
||||||
|
func TestAmpTargets(t *testing.T) {
|
||||||
|
a := &App{}
|
||||||
|
a.ampInsts = map[string]*ampInst{"left": {}, "right": {}, "third": {}}
|
||||||
|
|
||||||
|
// Unlinked: only the amplifier that was clicked.
|
||||||
|
if got := a.ampTargets("left", false); len(got) != 1 || got[0] != "left" {
|
||||||
|
t.Errorf("unlinked = %v, want just [left]", got)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Linked: every running amplifier, and the one clicked FIRST — a partial
|
||||||
|
// failure should still have done what the operator asked before it stopped.
|
||||||
|
|
||||||
|
got := a.ampTargets("right", true)
|
||||||
|
if len(got) != 3 {
|
||||||
|
t.Fatalf("linked = %v, want all three", got)
|
||||||
|
}
|
||||||
|
if got[0] != "right" {
|
||||||
|
t.Errorf("clicked amplifier is %q, want it first", got[0])
|
||||||
|
}
|
||||||
|
rest := append([]string{}, got[1:]...)
|
||||||
|
sort.Strings(rest)
|
||||||
|
if rest[0] != "left" || rest[1] != "third" {
|
||||||
|
t.Errorf("rest = %v, want the other two", rest)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16226,6 +16226,19 @@ func (a *App) ampInstByID(id string) *ampInst {
|
|||||||
|
|
||||||
// AmpOperate puts the given amp in OPERATE (true) or STANDBY (false).
|
// AmpOperate puts the given amp in OPERATE (true) or STANDBY (false).
|
||||||
func (a *App) AmpOperate(id string, on bool) error {
|
func (a *App) AmpOperate(id string, on bool) error {
|
||||||
|
// Fan out here rather than in the UI: the card and the docked widget both
|
||||||
|
// call this, and a coupling implemented in one of them would be missing from
|
||||||
|
// the other — which on a combiner means one amplifier keyed and one not.
|
||||||
|
var firstErr error
|
||||||
|
for _, tid := range a.ampTargets(id, a.GetAmpsLinked()) {
|
||||||
|
if err := a.ampOperateOne(tid, on); err != nil && firstErr == nil {
|
||||||
|
firstErr = err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return firstErr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *App) ampOperateOne(id string, on bool) error {
|
||||||
inst := a.ampInstByID(id)
|
inst := a.ampInstByID(id)
|
||||||
if inst == nil {
|
if inst == nil {
|
||||||
return fmt.Errorf("amplifier not running — check Settings → Amplifier")
|
return fmt.Errorf("amplifier not running — check Settings → Amplifier")
|
||||||
@@ -16250,6 +16263,17 @@ func (a *App) AmpPower(id string, on bool) (err error) {
|
|||||||
applog.Printf("amp %s: power %v failed: %v", id, on, err)
|
applog.Printf("amp %s: power %v failed: %v", id, on, err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
linked := a.GetAmpsLinked()
|
||||||
|
var firstErr error
|
||||||
|
for _, tid := range a.ampTargets(id, linked) {
|
||||||
|
if e := a.ampPowerOne(tid, on, linked); e != nil && firstErr == nil {
|
||||||
|
firstErr = e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return firstErr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *App) ampPowerOne(id string, on, linked bool) error {
|
||||||
inst := a.ampInstByID(id)
|
inst := a.ampInstByID(id)
|
||||||
if inst == nil {
|
if inst == nil {
|
||||||
return fmt.Errorf("amplifier not running — check Settings → Amplifier")
|
return fmt.Errorf("amplifier not running — check Settings → Amplifier")
|
||||||
@@ -16266,6 +16290,12 @@ func (a *App) AmpPower(id string, on bool) (err error) {
|
|||||||
}
|
}
|
||||||
return inst.acom.PowerOff()
|
return inst.acom.PowerOff()
|
||||||
}
|
}
|
||||||
|
// Not an error worth surfacing when linked: a PGXL alongside two SPEs simply
|
||||||
|
// has no power command on its direct link, and reporting that as a failure
|
||||||
|
// would make a successful pair look broken.
|
||||||
|
if linked {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return fmt.Errorf("power on/off is not available for this amplifier")
|
return fmt.Errorf("power on/off is not available for this amplifier")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17810,3 +17840,47 @@ func (a *App) SetCompactHeight(h int) {
|
|||||||
wruntime.WindowSetMinSize(a.ctx, 900, h)
|
wruntime.WindowSetMinSize(a.ctx, 900, h)
|
||||||
wruntime.WindowSetSize(a.ctx, w, h)
|
wruntime.WindowSetSize(a.ctx, w, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// keyAmpsLinked couples the configured amplifiers so ON, OFF and OPERATE act on
|
||||||
|
// all of them at once — the SPE CO1-2 combiner case.
|
||||||
|
//
|
||||||
|
// The combiner is an RF device: it sums two amplifiers and commands nothing. So
|
||||||
|
// "combined" operation is really two amplifiers that must be kept in the same
|
||||||
|
// state, and leaving one in OPERATE while the other sits in STANDBY is exactly
|
||||||
|
// what must not happen — the combiner would see power on one input only.
|
||||||
|
const keyAmpsLinked = "amps.linked"
|
||||||
|
|
||||||
|
// GetAmpsLinked reports whether the amplifiers are commanded together.
|
||||||
|
func (a *App) GetAmpsLinked() bool { return a.settingOr(keyAmpsLinked, "") == "1" }
|
||||||
|
|
||||||
|
// SetAmpsLinked turns coupling on or off.
|
||||||
|
func (a *App) SetAmpsLinked(on bool) error {
|
||||||
|
a.setSetting(keyAmpsLinked, boolStr(on))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ampTargets returns the amplifier ids a command should reach: the one asked
|
||||||
|
// for, or every running amplifier when they are linked.
|
||||||
|
//
|
||||||
|
// The METERS are deliberately untouched by this — each amplifier keeps its own
|
||||||
|
// bars. Two amps combined are still two amps, and an operator watching for one
|
||||||
|
// of them to run away needs to see them apart.
|
||||||
|
func (a *App) ampTargets(id string, linked bool) []string {
|
||||||
|
if !linked {
|
||||||
|
return []string{id}
|
||||||
|
}
|
||||||
|
a.ampsMu.Lock()
|
||||||
|
defer a.ampsMu.Unlock()
|
||||||
|
out := make([]string, 0, len(a.ampInsts))
|
||||||
|
// The one that was asked for goes FIRST, so a partial failure still did what
|
||||||
|
// the operator clicked before it stopped.
|
||||||
|
if _, ok := a.ampInsts[id]; ok {
|
||||||
|
out = append(out, id)
|
||||||
|
}
|
||||||
|
for k := range a.ampInsts {
|
||||||
|
if k != id {
|
||||||
|
out = append(out, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|||||||
+6
-2
@@ -2,8 +2,12 @@
|
|||||||
{
|
{
|
||||||
"version": "0.25.1",
|
"version": "0.25.1",
|
||||||
"date": "",
|
"date": "",
|
||||||
"en": [],
|
"en": [
|
||||||
"fr": []
|
"Amplifiers: an option commands them together — ON, OFF and OPERATE act on all at once, for a combiner. Each keeps its own meters."
|
||||||
|
],
|
||||||
|
"fr": [
|
||||||
|
"Amplificateurs : une option les commande ensemble — ON, OFF et OPERATE agissent sur tous à la fois, pour un combiner. Chacun garde ses mesures."
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"version": "0.25.0",
|
"version": "0.25.0",
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ import {
|
|||||||
GetADIFMonitor, SaveADIFMonitor, PickADIFMonitorFile,
|
GetADIFMonitor, SaveADIFMonitor, PickADIFMonitorFile,
|
||||||
GetRelayAuto, SaveRelayAuto, GetStationDevices,
|
GetRelayAuto, SaveRelayAuto, GetStationDevices,
|
||||||
GetAwardDefs, GetTrackedAwards, SaveTrackedAwards,
|
GetAwardDefs, GetTrackedAwards, SaveTrackedAwards,
|
||||||
GetBandOpenSettings, SaveBandOpenSettings, GetPSKReporterStatus, GetChaseNewGrids, SetChaseNewGrids, GetGridCacheStatus, GetSpotTTLMinutes, SetSpotTTLMinutes,
|
GetBandOpenSettings, SaveBandOpenSettings, GetPSKReporterStatus, GetChaseNewGrids, SetChaseNewGrids, GetGridCacheStatus, GetAmpsLinked, SetAmpsLinked, GetSpotTTLMinutes, SetSpotTTLMinutes,
|
||||||
} from '../../wailsjs/go/main/App';
|
} from '../../wailsjs/go/main/App';
|
||||||
import type { profile as profileModels } from '../../wailsjs/go/models';
|
import type { profile as profileModels } from '../../wailsjs/go/models';
|
||||||
import type { LookupSettingsForm, StationSettingsForm, ListsSettingsForm, ModePresetForm } from '@/types';
|
import type { LookupSettingsForm, StationSettingsForm, ListsSettingsForm, ModePresetForm } from '@/types';
|
||||||
@@ -1274,6 +1274,7 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
|
|||||||
// Amplifier list — operators can run SEVERAL amps (even two SPEs combined),
|
// Amplifier list — operators can run SEVERAL amps (even two SPEs combined),
|
||||||
// each with its own connection. Saved as a whole via SaveAmplifiers.
|
// each with its own connection. Saved as a whole via SaveAmplifiers.
|
||||||
const [amps, setAmps] = useState<AmpUI[]>([]);
|
const [amps, setAmps] = useState<AmpUI[]>([]);
|
||||||
|
const [ampsLinked, setAmpsLinked] = useState(false);
|
||||||
|
|
||||||
// WinKeyer CW keyer settings + macro editor.
|
// WinKeyer CW keyer settings + macro editor.
|
||||||
type WKMac = { label: string; text: string };
|
type WKMac = { label: string; text: string };
|
||||||
@@ -1571,6 +1572,7 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
|
|||||||
(async () => {
|
(async () => {
|
||||||
try { setBandOpen(await GetBandOpenSettings()); } catch { /* defaults stand */ }
|
try { setBandOpen(await GetBandOpenSettings()); } catch { /* defaults stand */ }
|
||||||
try { setChaseGrids(await GetChaseNewGrids()); } catch { /* defaults stand */ }
|
try { setChaseGrids(await GetChaseNewGrids()); } catch { /* defaults stand */ }
|
||||||
|
try { setAmpsLinked(await GetAmpsLinked()); } catch { /* defaults stand */ }
|
||||||
try { const n = await GetSpotTTLMinutes(); setSpotTTL(n); setSpotTTLText(String(n)); } catch { /* defaults stand */ }
|
try { const n = await GetSpotTTLMinutes(); setSpotTTL(n); setSpotTTLText(String(n)); } catch { /* defaults stand */ }
|
||||||
})();
|
})();
|
||||||
// Poll the feed while the panel is open: a live count is the only thing that
|
// Poll the feed while the panel is open: a live count is the only thing that
|
||||||
@@ -3408,6 +3410,18 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
|
|||||||
{amps.length === 0 && (
|
{amps.length === 0 && (
|
||||||
<p className="text-sm text-muted-foreground">{t('amp.none')}</p>
|
<p className="text-sm text-muted-foreground">{t('amp.none')}</p>
|
||||||
)}
|
)}
|
||||||
|
{/* Only offered with two or more: coupling one amplifier to itself is
|
||||||
|
a switch that cannot do anything. */}
|
||||||
|
{amps.length > 1 && (
|
||||||
|
<label className="flex items-start gap-2 text-sm cursor-pointer">
|
||||||
|
<Checkbox checked={ampsLinked} className="mt-0.5"
|
||||||
|
onCheckedChange={(c) => { setAmpsLinked(!!c); SetAmpsLinked(!!c).catch(() => {}); }} />
|
||||||
|
<span>
|
||||||
|
{t('amp.linked')}
|
||||||
|
<span className="block text-xs text-muted-foreground mt-0.5">{t('amp.linkedHint')}</span>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
)}
|
||||||
{amps.map((amp, i) => {
|
{amps.map((amp, i) => {
|
||||||
const brand = brandOf(amp.type);
|
const brand = brandOf(amp.type);
|
||||||
const isPGXL = brand === 'pgxl';
|
const isPGXL = brand === 'pgxl';
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ const en: Dict = {
|
|||||||
'gen.showBeam': 'Show the antenna beam heading on the Main map',
|
'gen.showBeam': 'Show the antenna beam heading on the Main map',
|
||||||
'gen.startEqEnd': 'QSO start time = end time', 'gen.startEqEndHint': '(matches LoTW when you call a while)',
|
'gen.startEqEnd': 'QSO start time = end time', 'gen.startEqEndHint': '(matches LoTW when you call a while)',
|
||||||
'gen.showQsoRate': 'Show QSO rate in the header', 'gen.showQsoRateHint': '(QSOs/hour, projected from the last 10 / 60 min)',
|
'gen.showQsoRate': 'Show QSO rate in the header', 'gen.showQsoRateHint': '(QSOs/hour, projected from the last 10 / 60 min)',
|
||||||
'gen.lookupOnBlur': 'Look up the callsign only after leaving the field', 'gen.lookupOnBlurHint': '(not while typing)', 'amp.hint': 'Configure one or several amplifiers — each panel card has a dropdown to pick which one it shows.', 'amp.none': 'No amplifier configured yet.', 'amp.namePh': 'Name (e.g. SPE left)', 'amp.remove': 'Remove this amplifier', 'amp.add': 'Add amplifier', 'amp.password': 'Remote code', 'amp.passwordPh': 'blank on LAN', 'amp.passwordHint': 'PowerGenius XL only: needed when reaching the amp remotely — it then announces "AUTH" and rejects every command ("Unauthorized") until you log in. Leave blank on the local network.', 'amp.freqOut': 'Send the frequency to the amplifier (band follow)', 'amp.freqPort': 'CAT/AUX COM port', 'amp.freqBroadcast': 'Also send unprompted', 'amp.freqPollOnly': 'No — answer the amplifier only', 'amp.freqEvery': 'Yes, every {ms} ms', 'amp.freqHint': 'OpsLog pretends to be a transceiver on this second port, in Kenwood format: set the amplifier to that command set (set 5 on an ACOM) at the same baud rate, and put it in OPERATE — in standby it acknowledges but does not switch band. An amplifier that POLLS (ACOM) needs nothing more; one that only LISTENS to the CAT line of the radio hears nothing unless you also turn on the unprompted send.',
|
'gen.lookupOnBlur': 'Look up the callsign only after leaving the field', 'gen.lookupOnBlurHint': '(not while typing)', 'amp.hint': 'Configure one or several amplifiers — each panel card has a dropdown to pick which one it shows.', 'amp.linked': 'Command these amplifiers together', 'amp.linkedHint': 'ON, OFF and OPERATE act on every amplifier at once — for a combiner, where one amp left in STANDBY would feed power to one input only. Each keeps its own meters.', 'amp.none': 'No amplifier configured yet.', 'amp.namePh': 'Name (e.g. SPE left)', 'amp.remove': 'Remove this amplifier', 'amp.add': 'Add amplifier', 'amp.password': 'Remote code', 'amp.passwordPh': 'blank on LAN', 'amp.passwordHint': 'PowerGenius XL only: needed when reaching the amp remotely — it then announces "AUTH" and rejects every command ("Unauthorized") until you log in. Leave blank on the local network.', 'amp.freqOut': 'Send the frequency to the amplifier (band follow)', 'amp.freqPort': 'CAT/AUX COM port', 'amp.freqBroadcast': 'Also send unprompted', 'amp.freqPollOnly': 'No — answer the amplifier only', 'amp.freqEvery': 'Yes, every {ms} ms', 'amp.freqHint': 'OpsLog pretends to be a transceiver on this second port, in Kenwood format: set the amplifier to that command set (set 5 on an ACOM) at the same baud rate, and put it in OPERATE — in standby it acknowledges but does not switch band. An amplifier that POLLS (ACOM) needs nothing more; one that only LISTENS to the CAT line of the radio hears nothing unless you also turn on the unprompted send.',
|
||||||
'gen.groupDigital': 'Group digital modes as one (DXCC-style)', 'gen.groupDigitalHint': '(matrix badges + cluster: FT8/FT4/RTTY… count as a single Digital mode; off = each digital mode is its own slot)',
|
'gen.groupDigital': 'Group digital modes as one (DXCC-style)', 'gen.groupDigitalHint': '(matrix badges + cluster: FT8/FT4/RTTY… count as a single Digital mode; off = each digital mode is its own slot)',
|
||||||
// Password encryption
|
// Password encryption
|
||||||
'gen.pwEnc': 'Password encryption',
|
'gen.pwEnc': 'Password encryption',
|
||||||
@@ -616,7 +616,7 @@ const fr: Dict = {
|
|||||||
'gen.showBeam': 'Afficher le cap de l\'antenne sur la carte principale',
|
'gen.showBeam': 'Afficher le cap de l\'antenne sur la carte principale',
|
||||||
'gen.startEqEnd': 'Heure de début du QSO = heure de fin', 'gen.startEqEndHint': '(correspond à LoTW quand tu appelles un moment)',
|
'gen.startEqEnd': 'Heure de début du QSO = heure de fin', 'gen.startEqEndHint': '(correspond à LoTW quand tu appelles un moment)',
|
||||||
'gen.showQsoRate': 'Afficher le rythme QSO dans la barre du haut', 'gen.showQsoRateHint': '(QSO/heure, projeté sur les 10 / 60 dernières min)',
|
'gen.showQsoRate': 'Afficher le rythme QSO dans la barre du haut', 'gen.showQsoRateHint': '(QSO/heure, projeté sur les 10 / 60 dernières min)',
|
||||||
'gen.lookupOnBlur': 'Rechercher l\'indicatif seulement après avoir quitté le champ', 'gen.lookupOnBlurHint': '(pas pendant la saisie)', 'amp.hint': 'Configurez un ou plusieurs amplificateurs — chaque carte de panneau a une liste déroulante pour choisir lequel afficher.', 'amp.none': 'Aucun amplificateur configuré.', 'amp.namePh': 'Nom (p. ex. SPE gauche)', 'amp.remove': 'Supprimer cet amplificateur', 'amp.add': 'Ajouter un amplificateur', 'amp.password': 'Code distant', 'amp.passwordPh': 'vide en LAN', 'amp.passwordHint': "PowerGenius XL uniquement : nécessaire pour joindre l'ampli à distance — il annonce alors « AUTH » et refuse toute commande (« Unauthorized ») tant qu'on n'est pas identifié. Laisse vide sur le réseau local.", 'amp.freqOut': "Envoyer la fréquence à l'amplificateur (suivi de bande)", 'amp.freqPort': 'Port COM CAT/AUX', 'amp.freqBroadcast': 'Envoyer aussi sans être interrogé', 'amp.freqPollOnly': "Non — répondre seulement à l'amplificateur", 'amp.freqEvery': 'Oui, toutes les {ms} ms', 'amp.freqHint': "OpsLog se fait passer pour un transceiver sur ce second port, au format Kenwood : réglez l'amplificateur sur ce jeu de commandes (le jeu 5 sur un ACOM) à la même vitesse, et mettez-le en OPERATE — en veille il acquitte mais ne change pas de bande. Un amplificateur qui INTERROGE (ACOM) n'a besoin de rien de plus ; un amplificateur qui se contente d'ÉCOUTER la liaison CAT de la radio n'entendra rien tant que l'envoi spontané n'est pas activé.",
|
'gen.lookupOnBlur': 'Rechercher l\'indicatif seulement après avoir quitté le champ', 'gen.lookupOnBlurHint': '(pas pendant la saisie)', 'amp.hint': 'Configurez un ou plusieurs amplificateurs — chaque carte de panneau a une liste déroulante pour choisir lequel afficher.', 'amp.linked': 'Commander ces amplificateurs ensemble', 'amp.linkedHint': "ON, OFF et OPERATE agissent sur tous les amplificateurs à la fois — pour un combiner, où un ampli resté en STANDBY n'alimenterait qu'une seule entrée. Chacun garde ses propres mesures.", 'amp.none': 'Aucun amplificateur configuré.', 'amp.namePh': 'Nom (p. ex. SPE gauche)', 'amp.remove': 'Supprimer cet amplificateur', 'amp.add': 'Ajouter un amplificateur', 'amp.password': 'Code distant', 'amp.passwordPh': 'vide en LAN', 'amp.passwordHint': "PowerGenius XL uniquement : nécessaire pour joindre l'ampli à distance — il annonce alors « AUTH » et refuse toute commande (« Unauthorized ») tant qu'on n'est pas identifié. Laisse vide sur le réseau local.", 'amp.freqOut': "Envoyer la fréquence à l'amplificateur (suivi de bande)", 'amp.freqPort': 'Port COM CAT/AUX', 'amp.freqBroadcast': 'Envoyer aussi sans être interrogé', 'amp.freqPollOnly': "Non — répondre seulement à l'amplificateur", 'amp.freqEvery': 'Oui, toutes les {ms} ms', 'amp.freqHint': "OpsLog se fait passer pour un transceiver sur ce second port, au format Kenwood : réglez l'amplificateur sur ce jeu de commandes (le jeu 5 sur un ACOM) à la même vitesse, et mettez-le en OPERATE — en veille il acquitte mais ne change pas de bande. Un amplificateur qui INTERROGE (ACOM) n'a besoin de rien de plus ; un amplificateur qui se contente d'ÉCOUTER la liaison CAT de la radio n'entendra rien tant que l'envoi spontané n'est pas activé.",
|
||||||
'gen.groupDigital': 'Regrouper les modes digitaux en un seul (style DXCC)', 'gen.groupDigitalHint': '(badges de la matrice + cluster : FT8/FT4/RTTY… comptent comme un seul mode Digital ; décoché = chaque mode digital est un slot distinct)',
|
'gen.groupDigital': 'Regrouper les modes digitaux en un seul (style DXCC)', 'gen.groupDigitalHint': '(badges de la matrice + cluster : FT8/FT4/RTTY… comptent comme un seul mode Digital ; décoché = chaque mode digital est un slot distinct)',
|
||||||
// Chiffrement des mots de passe
|
// Chiffrement des mots de passe
|
||||||
'gen.pwEnc': 'Chiffrement des mots de passe',
|
'gen.pwEnc': 'Chiffrement des mots de passe',
|
||||||
|
|||||||
Vendored
+4
@@ -366,6 +366,8 @@ export function GetAmpStatuses():Promise<Array<main.AmpStatus>>;
|
|||||||
|
|
||||||
export function GetAmplifiers():Promise<Array<main.AmpConfig>>;
|
export function GetAmplifiers():Promise<Array<main.AmpConfig>>;
|
||||||
|
|
||||||
|
export function GetAmpsLinked():Promise<boolean>;
|
||||||
|
|
||||||
export function GetAntGeniusSettings():Promise<main.AntGeniusSettings>;
|
export function GetAntGeniusSettings():Promise<main.AntGeniusSettings>;
|
||||||
|
|
||||||
export function GetAntGeniusStatus():Promise<antgenius.Status>;
|
export function GetAntGeniusStatus():Promise<antgenius.Status>;
|
||||||
@@ -972,6 +974,8 @@ export function SetActiveRotor(arg1:number):Promise<void>;
|
|||||||
|
|
||||||
export function SetAlertEmailTo(arg1:string):Promise<void>;
|
export function SetAlertEmailTo(arg1:string):Promise<void>;
|
||||||
|
|
||||||
|
export function SetAmpsLinked(arg1:boolean):Promise<void>;
|
||||||
|
|
||||||
export function SetCATFrequency(arg1:number):Promise<void>;
|
export function SetCATFrequency(arg1:number):Promise<void>;
|
||||||
|
|
||||||
export function SetCATMode(arg1:string):Promise<void>;
|
export function SetCATMode(arg1:string):Promise<void>;
|
||||||
|
|||||||
@@ -674,6 +674,10 @@ export function GetAmplifiers() {
|
|||||||
return window['go']['main']['App']['GetAmplifiers']();
|
return window['go']['main']['App']['GetAmplifiers']();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function GetAmpsLinked() {
|
||||||
|
return window['go']['main']['App']['GetAmpsLinked']();
|
||||||
|
}
|
||||||
|
|
||||||
export function GetAntGeniusSettings() {
|
export function GetAntGeniusSettings() {
|
||||||
return window['go']['main']['App']['GetAntGeniusSettings']();
|
return window['go']['main']['App']['GetAntGeniusSettings']();
|
||||||
}
|
}
|
||||||
@@ -1886,6 +1890,10 @@ export function SetAlertEmailTo(arg1) {
|
|||||||
return window['go']['main']['App']['SetAlertEmailTo'](arg1);
|
return window['go']['main']['App']['SetAlertEmailTo'](arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function SetAmpsLinked(arg1) {
|
||||||
|
return window['go']['main']['App']['SetAmpsLinked'](arg1);
|
||||||
|
}
|
||||||
|
|
||||||
export function SetCATFrequency(arg1) {
|
export function SetCATFrequency(arg1) {
|
||||||
return window['go']['main']['App']['SetCATFrequency'](arg1);
|
return window['go']['main']['App']['SetCATFrequency'](arg1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user