feat: generalize Settings 'Power Genius' into 'Amplifier' (type + serial/IP transport) for SPE Expert
Renames the Hardware section to Amplifier and adds an amplifier-type selector (4O3A PowerGenius XL, SPE Expert 1.3K-FA / 1.5K-FA / 2K-FA) plus a transport choice for the SPE amps: USB (serial COM + baud) or Network (RS232-to-Ethernet IP:port). PGXLSettings gains Type/Transport/ComPort/Baud (keys keep the pgxl.* prefix for back-compat). PowerGenius still drives over TCP; SPE settings are stored but control is not wired yet (needs the SPE serial protocol).
This commit is contained in:
@@ -182,10 +182,16 @@ const (
|
|||||||
keyAntGeniusHost = "antgenius.host"
|
keyAntGeniusHost = "antgenius.host"
|
||||||
keyAntGeniusPassword = "antgenius.password" // remote/AUTH password (blank on LAN)
|
keyAntGeniusPassword = "antgenius.password" // remote/AUTH password (blank on LAN)
|
||||||
|
|
||||||
// PowerGenius XL (4O3A) amplifier fan-mode control — Hardware → PowerGenius.
|
// Amplifier control — Hardware → Amplifier (PowerGenius XL over TCP; SPE Expert
|
||||||
keyPGXLEnabled = "pgxl.enabled"
|
// over USB serial or an RS232-to-Ethernet bridge). Keys keep the pgxl.* prefix
|
||||||
keyPGXLHost = "pgxl.host"
|
// for backward compatibility with existing saved settings.
|
||||||
keyPGXLPort = "pgxl.port"
|
keyPGXLEnabled = "pgxl.enabled"
|
||||||
|
keyPGXLHost = "pgxl.host"
|
||||||
|
keyPGXLPort = "pgxl.port"
|
||||||
|
keyPGXLType = "pgxl.type" // "pgxl" | "spe13" | "spe15" | "spe2k"
|
||||||
|
keyPGXLTransport = "pgxl.transport" // "tcp" | "serial"
|
||||||
|
keyPGXLComPort = "pgxl.com_port"
|
||||||
|
keyPGXLBaud = "pgxl.baud"
|
||||||
|
|
||||||
// WinKeyer CW keyer (serial) — Hardware → CW Keyer.
|
// WinKeyer CW keyer (serial) — Hardware → CW Keyer.
|
||||||
keyWKEnabled = "winkeyer.enabled"
|
keyWKEnabled = "winkeyer.enabled"
|
||||||
@@ -12131,19 +12137,25 @@ func (a *App) AntGeniusDeselect(port int) error {
|
|||||||
|
|
||||||
// ── PowerGenius XL (4O3A) amplifier fan control (TCP, default port 9008) ─────
|
// ── PowerGenius XL (4O3A) amplifier fan control (TCP, default port 9008) ─────
|
||||||
|
|
||||||
// PGXLSettings is the JSON shape for the Hardware → PowerGenius panel.
|
// PGXLSettings is the JSON shape for the Hardware → Amplifier panel. It covers
|
||||||
|
// the 4O3A PowerGenius XL (TCP) and the SPE Expert amps (USB serial or an
|
||||||
|
// RS232-to-Ethernet bridge). The type name is kept for binding compatibility.
|
||||||
type PGXLSettings struct {
|
type PGXLSettings struct {
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
Host string `json:"host"`
|
Type string `json:"type"` // "pgxl" | "spe13" | "spe15" | "spe2k"
|
||||||
Port int `json:"port"`
|
Transport string `json:"transport"` // "tcp" | "serial"
|
||||||
|
Host string `json:"host"` // TCP transport
|
||||||
|
Port int `json:"port"` // TCP transport
|
||||||
|
ComPort string `json:"com_port"` // serial transport
|
||||||
|
Baud int `json:"baud"` // serial transport
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) GetPGXLSettings() (PGXLSettings, error) {
|
func (a *App) GetPGXLSettings() (PGXLSettings, error) {
|
||||||
out := PGXLSettings{Port: 9008}
|
out := PGXLSettings{Type: "pgxl", Transport: "tcp", Port: 9008, Baud: 115200}
|
||||||
if a.settings == nil {
|
if a.settings == nil {
|
||||||
return out, fmt.Errorf("db not initialized")
|
return out, fmt.Errorf("db not initialized")
|
||||||
}
|
}
|
||||||
m, err := a.settings.GetMany(a.ctx, keyPGXLEnabled, keyPGXLHost, keyPGXLPort)
|
m, err := a.settings.GetMany(a.ctx, keyPGXLEnabled, keyPGXLHost, keyPGXLPort, keyPGXLType, keyPGXLTransport, keyPGXLComPort, keyPGXLBaud)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
@@ -12152,6 +12164,16 @@ func (a *App) GetPGXLSettings() (PGXLSettings, error) {
|
|||||||
if p, _ := strconv.Atoi(m[keyPGXLPort]); p > 0 && p <= 65535 {
|
if p, _ := strconv.Atoi(m[keyPGXLPort]); p > 0 && p <= 65535 {
|
||||||
out.Port = p
|
out.Port = p
|
||||||
}
|
}
|
||||||
|
if t := strings.TrimSpace(m[keyPGXLType]); t != "" {
|
||||||
|
out.Type = t
|
||||||
|
}
|
||||||
|
if tr := strings.TrimSpace(m[keyPGXLTransport]); tr != "" {
|
||||||
|
out.Transport = tr
|
||||||
|
}
|
||||||
|
out.ComPort = m[keyPGXLComPort]
|
||||||
|
if b, _ := strconv.Atoi(m[keyPGXLBaud]); b > 0 {
|
||||||
|
out.Baud = b
|
||||||
|
}
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12162,10 +12184,23 @@ func (a *App) SavePGXLSettings(s PGXLSettings) error {
|
|||||||
if s.Port <= 0 || s.Port > 65535 {
|
if s.Port <= 0 || s.Port > 65535 {
|
||||||
s.Port = 9008
|
s.Port = 9008
|
||||||
}
|
}
|
||||||
|
if s.Baud <= 0 {
|
||||||
|
s.Baud = 115200
|
||||||
|
}
|
||||||
|
if s.Type == "" {
|
||||||
|
s.Type = "pgxl"
|
||||||
|
}
|
||||||
|
if s.Transport == "" {
|
||||||
|
s.Transport = "tcp"
|
||||||
|
}
|
||||||
for k, v := range map[string]string{
|
for k, v := range map[string]string{
|
||||||
keyPGXLEnabled: boolStr(s.Enabled),
|
keyPGXLEnabled: boolStr(s.Enabled),
|
||||||
keyPGXLHost: strings.TrimSpace(s.Host),
|
keyPGXLHost: strings.TrimSpace(s.Host),
|
||||||
keyPGXLPort: strconv.Itoa(s.Port),
|
keyPGXLPort: strconv.Itoa(s.Port),
|
||||||
|
keyPGXLType: s.Type,
|
||||||
|
keyPGXLTransport: s.Transport,
|
||||||
|
keyPGXLComPort: strings.TrimSpace(s.ComPort),
|
||||||
|
keyPGXLBaud: strconv.Itoa(s.Baud),
|
||||||
} {
|
} {
|
||||||
if err := a.settings.Set(a.ctx, k, v); err != nil {
|
if err := a.settings.Set(a.ctx, k, v); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -12185,7 +12220,17 @@ func (a *App) startPGXL() {
|
|||||||
a.pgxl = nil
|
a.pgxl = nil
|
||||||
}
|
}
|
||||||
s, err := a.GetPGXLSettings()
|
s, err := a.GetPGXLSettings()
|
||||||
if err != nil || !s.Enabled || strings.TrimSpace(s.Host) == "" {
|
if err != nil || !s.Enabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Only the PowerGenius XL (TCP) is driven for now. SPE Expert control (serial /
|
||||||
|
// RS232-to-Ethernet) is a separate protocol, not yet implemented — its settings
|
||||||
|
// are stored but no client is started.
|
||||||
|
if s.Type != "" && s.Type != "pgxl" {
|
||||||
|
applog.Printf("amplifier: type %q selected — control not implemented yet (settings saved)", s.Type)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(s.Host) == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
a.pgxl = powergenius.New(s.Host, s.Port)
|
a.pgxl = powergenius.New(s.Host, s.Port)
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ const SECTION_LABELS: Partial<Record<SectionId, string>> = {
|
|||||||
winkeyer: 'CW Keyer',
|
winkeyer: 'CW Keyer',
|
||||||
antenna: 'Ultrabeam / Steppir',
|
antenna: 'Ultrabeam / Steppir',
|
||||||
antgenius: 'Antenna Genius',
|
antgenius: 'Antenna Genius',
|
||||||
pgxl: 'Power Genius',
|
pgxl: 'Amplifier',
|
||||||
flex: 'FlexRadio',
|
flex: 'FlexRadio',
|
||||||
relayauto: 'Relay auto-control',
|
relayauto: 'Relay auto-control',
|
||||||
audio: 'Audio devices',
|
audio: 'Audio devices',
|
||||||
@@ -1013,8 +1013,9 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
|
|||||||
// Antenna Genius (4O3A) switch settings — TCP port is fixed at 9007.
|
// Antenna Genius (4O3A) switch settings — TCP port is fixed at 9007.
|
||||||
const [antgenius, setAntgenius] = useState<{ enabled: boolean; host: string; password: string }>({ enabled: false, host: '', password: '' });
|
const [antgenius, setAntgenius] = useState<{ enabled: boolean; host: string; password: string }>({ enabled: false, host: '', password: '' });
|
||||||
|
|
||||||
// PowerGenius XL (4O3A) amp fan-control settings.
|
// Amplifier control settings (PowerGenius XL over TCP; SPE Expert over serial/IP).
|
||||||
const [pgxl, setPgxl] = useState<{ enabled: boolean; host: string; port: number }>({ enabled: false, host: '', port: 9008 });
|
const [pgxl, setPgxl] = useState<{ enabled: boolean; type: string; transport: string; host: string; port: number; com_port: string; baud: number }>(
|
||||||
|
{ enabled: false, type: 'pgxl', transport: 'tcp', host: '', port: 9008, com_port: '', baud: 115200 });
|
||||||
|
|
||||||
// WinKeyer CW keyer settings + macro editor.
|
// WinKeyer CW keyer settings + macro editor.
|
||||||
type WKMac = { label: string; text: string };
|
type WKMac = { label: string; text: string };
|
||||||
@@ -2645,36 +2646,89 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
|
|||||||
}
|
}
|
||||||
|
|
||||||
function PGXLPanelSettings() {
|
function PGXLPanelSettings() {
|
||||||
|
const isPGXL = pgxl.type === 'pgxl';
|
||||||
|
const isSerial = pgxl.transport === 'serial';
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SectionHeader
|
<SectionHeader title="Amplifier" />
|
||||||
title="Power Genius XL"
|
|
||||||
/>
|
|
||||||
<div className="space-y-4 max-w-xl">
|
<div className="space-y-4 max-w-xl">
|
||||||
<label className="flex items-center gap-2 text-sm cursor-pointer">
|
<label className="flex items-center gap-2 text-sm cursor-pointer">
|
||||||
<Checkbox checked={pgxl.enabled} onCheckedChange={(c) => setPgxl((s) => ({ ...s, enabled: !!c }))} />
|
<Checkbox checked={pgxl.enabled} onCheckedChange={(c) => setPgxl((s) => ({ ...s, enabled: !!c }))} />
|
||||||
Enable PowerGenius fan control
|
Enable amplifier control
|
||||||
</label>
|
</label>
|
||||||
<div className="grid grid-cols-3 gap-3">
|
|
||||||
<div className="space-y-1 col-span-2">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<Label>Host / IP</Label>
|
|
||||||
<Input
|
|
||||||
value={pgxl.host ?? ''}
|
|
||||||
onChange={(e) => setPgxl((s) => ({ ...s, host: e.target.value }))}
|
|
||||||
placeholder="192.168.1.70"
|
|
||||||
className="font-mono"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<Label>TCP port</Label>
|
<Label>Amplifier</Label>
|
||||||
<Input
|
<Select value={pgxl.type} onValueChange={(v) => setPgxl((s) => ({ ...s, type: v, transport: v === 'pgxl' ? 'tcp' : s.transport }))}>
|
||||||
type="number" min={1} max={65535}
|
<SelectTrigger className="h-9"><SelectValue /></SelectTrigger>
|
||||||
value={pgxl.port}
|
<SelectContent>
|
||||||
onChange={(e) => setPgxl((s) => ({ ...s, port: parseInt(e.target.value) || 9008 }))}
|
<SelectItem value="pgxl">4O3A PowerGenius XL</SelectItem>
|
||||||
className="font-mono"
|
<SelectItem value="spe13">SPE Expert 1.3K-FA</SelectItem>
|
||||||
/>
|
<SelectItem value="spe15">SPE Expert 1.5K-FA</SelectItem>
|
||||||
|
<SelectItem value="spe2k">SPE Expert 2K-FA</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
{/* PowerGenius is TCP-only; SPE amps connect over USB serial or an
|
||||||
|
RS232-to-Ethernet bridge, so they offer both. */}
|
||||||
|
{!isPGXL && (
|
||||||
|
<div className="space-y-1">
|
||||||
|
<Label>Connection</Label>
|
||||||
|
<Select value={pgxl.transport} onValueChange={(v) => setPgxl((s) => ({ ...s, transport: v }))}>
|
||||||
|
<SelectTrigger className="h-9"><SelectValue /></SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="serial">USB (serial COM)</SelectItem>
|
||||||
|
<SelectItem value="tcp">Network (RS232-to-Ethernet)</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{isSerial ? (
|
||||||
|
<div className="grid grid-cols-3 gap-3">
|
||||||
|
<div className="space-y-1 col-span-2">
|
||||||
|
<Label>COM port</Label>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Select value={pgxl.com_port || '_'} onValueChange={(v) => setPgxl((s) => ({ ...s, com_port: v === '_' ? '' : v }))}>
|
||||||
|
<SelectTrigger className="h-9 flex-1"><SelectValue placeholder="— COM —" /></SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
{wkPorts.length === 0 && <SelectItem value="_" disabled>No ports found</SelectItem>}
|
||||||
|
{wkPorts.map((p) => <SelectItem key={p} value={p}>{p}</SelectItem>)}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<Button size="sm" variant="outline" className="h-9" onClick={() => ListSerialPorts().then((p) => setWkPorts((p ?? []) as string[])).catch(() => {})}>
|
||||||
|
<ArrowDown className="size-3.5 rotate-90" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-1">
|
||||||
|
<Label>Baud</Label>
|
||||||
|
<Input type="number" min={1200} value={pgxl.baud}
|
||||||
|
onChange={(e) => setPgxl((s) => ({ ...s, baud: parseInt(e.target.value) || 115200 }))} className="font-mono" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="grid grid-cols-3 gap-3">
|
||||||
|
<div className="space-y-1 col-span-2">
|
||||||
|
<Label>Host / IP</Label>
|
||||||
|
<Input value={pgxl.host ?? ''} onChange={(e) => setPgxl((s) => ({ ...s, host: e.target.value }))}
|
||||||
|
placeholder="192.168.1.70" className="font-mono" />
|
||||||
|
</div>
|
||||||
|
<div className="space-y-1">
|
||||||
|
<Label>TCP port</Label>
|
||||||
|
<Input type="number" min={1} max={65535} value={pgxl.port}
|
||||||
|
onChange={(e) => setPgxl((s) => ({ ...s, port: parseInt(e.target.value) || 9008 }))} className="font-mono" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!isPGXL && (
|
||||||
|
<p className="text-xs text-warning">
|
||||||
|
SPE Expert control is not wired up yet — these settings are saved, but OpsLog can't command the amp until its serial protocol is implemented.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ const en: Dict = {
|
|||||||
'uscty.backfillDone': '{s} US QSOs scanned · {c} counties, {g} grids filled.',
|
'uscty.backfillDone': '{s} US QSOs scanned · {c} counties, {g} grids filled.',
|
||||||
'station.title': 'Station Control', 'station.rotator': 'Rotator', 'station.rotatorNoRead': 'No heading read', 'station.pattern': 'Pattern', 'station.bi': 'Bi', 'station.retract': 'Retract elements', 'station.moving': 'MOVING', 'station.elements': 'Elements (mm)', 'station.read': 'Read', 'station.readLengths': 'Read current element lengths from the controller', 'station.noLengths': 'Lengths unknown — click Read to fetch them from the controller.', 'station.element': 'Element', 'station.reflector': 'Reflector', 'station.driven': 'Driven', 'station.director': 'Dir', 'station.set': 'Set', 'station.elementsHint': 'Each press lengthens/shortens the element by 2 mm (like the physical console). Verify which element responds on your antenna.', 'station.setExactLen': 'Click to type the exact current length (fixes the baseline if the auto-read is off).', 'station.atMax': 'Controller refused — the element is likely at its maximum length for this band, so it can\'t extend further.', 'station.go': 'Go', 'station.stop': 'Stop', 'station.dragHint': 'Drag a widget by its card to reorder. Pick a column count to lay them out in a grid.', 'station.colsAuto': 'Auto', 'station.addDevice': 'Add device', 'station.editDevice': 'Edit device', 'station.empty': 'No relay boards yet. Add a WebSwitch 1216H or a KMTronic 8-relay board to control your station power and accessories.', 'station.online': 'Online', 'station.offline': 'Offline', 'station.edit': 'Edit', 'station.delete': 'Delete', 'station.relay': 'Relay', 'station.on': 'ON', 'station.off': 'OFF', 'station.type': 'Device type', 'station.name': 'Name', 'station.host': 'Host / IP', 'station.user': 'Username', 'station.pass': 'Password', 'station.optional': 'optional', 'station.ftdiSerial': 'FTDI serial number', 'station.detect': 'Detect', 'station.ftdiHint': 'The Denkovi board is driven via FTDI bit-bang (not the COM port). Pick its serial (e.g. DAE0006K). Needs the FTDI D2XX driver installed.', 'station.channels': 'Relays', 'station.comPort': 'COM port', 'station.noPorts': 'No ports found', 'station.usbRelayHint': 'Cheap USB-serial relay boards (CH340/LCUS) using the A0 command protocol. If yours does not switch, tell me its model / command set.', 'station.labels': 'Relay labels', 'station.cancel': 'Cancel', 'station.save': 'Save',
|
'station.title': 'Station Control', 'station.rotator': 'Rotator', 'station.rotatorNoRead': 'No heading read', 'station.pattern': 'Pattern', 'station.bi': 'Bi', 'station.retract': 'Retract elements', 'station.moving': 'MOVING', 'station.elements': 'Elements (mm)', 'station.read': 'Read', 'station.readLengths': 'Read current element lengths from the controller', 'station.noLengths': 'Lengths unknown — click Read to fetch them from the controller.', 'station.element': 'Element', 'station.reflector': 'Reflector', 'station.driven': 'Driven', 'station.director': 'Dir', 'station.set': 'Set', 'station.elementsHint': 'Each press lengthens/shortens the element by 2 mm (like the physical console). Verify which element responds on your antenna.', 'station.setExactLen': 'Click to type the exact current length (fixes the baseline if the auto-read is off).', 'station.atMax': 'Controller refused — the element is likely at its maximum length for this band, so it can\'t extend further.', 'station.go': 'Go', 'station.stop': 'Stop', 'station.dragHint': 'Drag a widget by its card to reorder. Pick a column count to lay them out in a grid.', 'station.colsAuto': 'Auto', 'station.addDevice': 'Add device', 'station.editDevice': 'Edit device', 'station.empty': 'No relay boards yet. Add a WebSwitch 1216H or a KMTronic 8-relay board to control your station power and accessories.', 'station.online': 'Online', 'station.offline': 'Offline', 'station.edit': 'Edit', 'station.delete': 'Delete', 'station.relay': 'Relay', 'station.on': 'ON', 'station.off': 'OFF', 'station.type': 'Device type', 'station.name': 'Name', 'station.host': 'Host / IP', 'station.user': 'Username', 'station.pass': 'Password', 'station.optional': 'optional', 'station.ftdiSerial': 'FTDI serial number', 'station.detect': 'Detect', 'station.ftdiHint': 'The Denkovi board is driven via FTDI bit-bang (not the COM port). Pick its serial (e.g. DAE0006K). Needs the FTDI D2XX driver installed.', 'station.channels': 'Relays', 'station.comPort': 'COM port', 'station.noPorts': 'No ports found', 'station.usbRelayHint': 'Cheap USB-serial relay boards (CH340/LCUS) using the A0 command protocol. If yours does not switch, tell me its model / command set.', 'station.labels': 'Relay labels', 'station.cancel': 'Cancel', 'station.save': 'Save',
|
||||||
'sec.awards': 'Awards', 'sec.cat': 'CAT interface', 'sec.rotator': 'Rotator', 'sec.winkeyer': 'CW Keyer',
|
'sec.awards': 'Awards', 'sec.cat': 'CAT interface', 'sec.rotator': 'Rotator', 'sec.winkeyer': 'CW Keyer',
|
||||||
'sec.antenna': 'Ultrabeam / Steppir', 'sec.antgenius': 'Antenna Genius', 'sec.pgxl': 'Power Genius', 'sec.flex': 'FlexRadio', 'sec.audio': 'Audio devices',
|
'sec.antenna': 'Ultrabeam / Steppir', 'sec.antgenius': 'Antenna Genius', 'sec.pgxl': 'Amplifier', 'sec.flex': 'FlexRadio', 'sec.audio': 'Audio devices',
|
||||||
'sec.relayauto': 'Relay auto-control',
|
'sec.relayauto': 'Relay auto-control',
|
||||||
'relayauto.hint': 'Automatically switch Station Control relays from the rig frequency / band (like PstRotator). Each relay: a frequency window (ON inside, OFF outside) or a set of bands. Relays are set up in the Station Control panel.',
|
'relayauto.hint': 'Automatically switch Station Control relays from the rig frequency / band (like PstRotator). Each relay: a frequency window (ON inside, OFF outside) or a set of bands. Relays are set up in the Station Control panel.',
|
||||||
'relayauto.enable': 'Enable relay auto-control',
|
'relayauto.enable': 'Enable relay auto-control',
|
||||||
@@ -446,7 +446,7 @@ const fr: Dict = {
|
|||||||
'uscty.backfillDone': '{s} QSO US analysés · {c} comtés, {g} locators remplis.',
|
'uscty.backfillDone': '{s} QSO US analysés · {c} comtés, {g} locators remplis.',
|
||||||
'station.title': 'Contrôle station', 'station.rotator': 'Rotator', 'station.rotatorNoRead': 'Azimut non lu', 'station.pattern': 'Diagramme', 'station.bi': 'Bi', 'station.retract': 'Rétracter les éléments', 'station.moving': 'EN MOUVEMENT', 'station.elements': 'Éléments (mm)', 'station.read': 'Lire', 'station.readLengths': 'Lire les longueurs actuelles depuis le contrôleur', 'station.noLengths': 'Longueurs inconnues — clique sur Lire pour les récupérer depuis le contrôleur.', 'station.element': 'Élément', 'station.reflector': 'Réflecteur', 'station.driven': 'Radiateur', 'station.director': 'Dir', 'station.set': 'Régler', 'station.elementsHint': "Chaque appui allonge/raccourcit l'élément de 2 mm (comme le pupitre). Vérifie quel élément répond sur ton antenne.", 'station.setExactLen': "Clique pour taper la longueur actuelle exacte (recale la base si la lecture auto est fausse).", 'station.atMax': "Refusé par le contrôleur — l'élément est probablement en butée (longueur max pour cette bande), il ne peut plus s'allonger.", 'station.go': 'Aller', 'station.stop': 'Stop', 'station.dragHint': 'Glisse une carte pour réordonner. Choisis un nombre de colonnes pour la disposition.', 'station.colsAuto': 'Auto', 'station.addDevice': 'Ajouter un appareil', 'station.editDevice': "Modifier l'appareil", 'station.empty': "Aucune carte relais. Ajoute un WebSwitch 1216H ou une carte KMTronic 8 relais pour piloter l'alimentation et les accessoires de ta station.", 'station.online': 'En ligne', 'station.offline': 'Hors ligne', 'station.edit': 'Modifier', 'station.delete': 'Supprimer', 'station.relay': 'Relais', 'station.on': 'ON', 'station.off': 'OFF', 'station.type': "Type d'appareil", 'station.name': 'Nom', 'station.host': 'Hôte / IP', 'station.user': "Nom d'utilisateur", 'station.pass': 'Mot de passe', 'station.optional': 'optionnel', 'station.ftdiSerial': 'Numéro de série FTDI', 'station.detect': 'Détecter', 'station.ftdiHint': "La carte Denkovi se pilote en FTDI bit-bang (pas via le port COM). Choisis son numéro de série (ex. DAE0006K). Nécessite le driver FTDI D2XX installé.", 'station.channels': 'Relais', 'station.comPort': 'Port COM', 'station.noPorts': 'Aucun port', 'station.usbRelayHint': "Cartes USB-série bon marché (CH340/LCUS) protocole A0. Si la tienne ne commute pas, donne-moi le modèle / jeu de commandes.", 'station.labels': 'Libellés des relais', 'station.cancel': 'Annuler', 'station.save': 'Enregistrer',
|
'station.title': 'Contrôle station', 'station.rotator': 'Rotator', 'station.rotatorNoRead': 'Azimut non lu', 'station.pattern': 'Diagramme', 'station.bi': 'Bi', 'station.retract': 'Rétracter les éléments', 'station.moving': 'EN MOUVEMENT', 'station.elements': 'Éléments (mm)', 'station.read': 'Lire', 'station.readLengths': 'Lire les longueurs actuelles depuis le contrôleur', 'station.noLengths': 'Longueurs inconnues — clique sur Lire pour les récupérer depuis le contrôleur.', 'station.element': 'Élément', 'station.reflector': 'Réflecteur', 'station.driven': 'Radiateur', 'station.director': 'Dir', 'station.set': 'Régler', 'station.elementsHint': "Chaque appui allonge/raccourcit l'élément de 2 mm (comme le pupitre). Vérifie quel élément répond sur ton antenne.", 'station.setExactLen': "Clique pour taper la longueur actuelle exacte (recale la base si la lecture auto est fausse).", 'station.atMax': "Refusé par le contrôleur — l'élément est probablement en butée (longueur max pour cette bande), il ne peut plus s'allonger.", 'station.go': 'Aller', 'station.stop': 'Stop', 'station.dragHint': 'Glisse une carte pour réordonner. Choisis un nombre de colonnes pour la disposition.', 'station.colsAuto': 'Auto', 'station.addDevice': 'Ajouter un appareil', 'station.editDevice': "Modifier l'appareil", 'station.empty': "Aucune carte relais. Ajoute un WebSwitch 1216H ou une carte KMTronic 8 relais pour piloter l'alimentation et les accessoires de ta station.", 'station.online': 'En ligne', 'station.offline': 'Hors ligne', 'station.edit': 'Modifier', 'station.delete': 'Supprimer', 'station.relay': 'Relais', 'station.on': 'ON', 'station.off': 'OFF', 'station.type': "Type d'appareil", 'station.name': 'Nom', 'station.host': 'Hôte / IP', 'station.user': "Nom d'utilisateur", 'station.pass': 'Mot de passe', 'station.optional': 'optionnel', 'station.ftdiSerial': 'Numéro de série FTDI', 'station.detect': 'Détecter', 'station.ftdiHint': "La carte Denkovi se pilote en FTDI bit-bang (pas via le port COM). Choisis son numéro de série (ex. DAE0006K). Nécessite le driver FTDI D2XX installé.", 'station.channels': 'Relais', 'station.comPort': 'Port COM', 'station.noPorts': 'Aucun port', 'station.usbRelayHint': "Cartes USB-série bon marché (CH340/LCUS) protocole A0. Si la tienne ne commute pas, donne-moi le modèle / jeu de commandes.", 'station.labels': 'Libellés des relais', 'station.cancel': 'Annuler', 'station.save': 'Enregistrer',
|
||||||
'sec.awards': 'Diplômes', 'sec.cat': 'Interface CAT', 'sec.rotator': 'Rotator', 'sec.winkeyer': 'Manipulateur CW',
|
'sec.awards': 'Diplômes', 'sec.cat': 'Interface CAT', 'sec.rotator': 'Rotator', 'sec.winkeyer': 'Manipulateur CW',
|
||||||
'sec.antenna': 'Antenne motorisée', 'sec.antgenius': 'Antenna Genius', 'sec.pgxl': 'Power Genius', 'sec.flex': 'FlexRadio', 'sec.audio': 'Périphériques audio',
|
'sec.antenna': 'Antenne motorisée', 'sec.antgenius': 'Antenna Genius', 'sec.pgxl': 'Amplificateur', 'sec.flex': 'FlexRadio', 'sec.audio': 'Périphériques audio',
|
||||||
'sec.relayauto': 'Relais automatiques',
|
'sec.relayauto': 'Relais automatiques',
|
||||||
'relayauto.hint': "Commute automatiquement les relais du Station Control selon la fréquence / bande du poste (comme PstRotator). Par relais : une plage de fréquence (ON dedans, OFF dehors) ou un ensemble de bandes. Les relais se configurent dans le panneau Station Control.",
|
'relayauto.hint': "Commute automatiquement les relais du Station Control selon la fréquence / bande du poste (comme PstRotator). Par relais : une plage de fréquence (ON dedans, OFF dehors) ou un ensemble de bandes. Les relais se configurent dans le panneau Station Control.",
|
||||||
'relayauto.enable': 'Activer les relais automatiques',
|
'relayauto.enable': 'Activer les relais automatiques',
|
||||||
|
|||||||
@@ -2161,8 +2161,12 @@ export namespace main {
|
|||||||
}
|
}
|
||||||
export class PGXLSettings {
|
export class PGXLSettings {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
|
type: string;
|
||||||
|
transport: string;
|
||||||
host: string;
|
host: string;
|
||||||
port: number;
|
port: number;
|
||||||
|
com_port: string;
|
||||||
|
baud: number;
|
||||||
|
|
||||||
static createFrom(source: any = {}) {
|
static createFrom(source: any = {}) {
|
||||||
return new PGXLSettings(source);
|
return new PGXLSettings(source);
|
||||||
@@ -2171,8 +2175,12 @@ export namespace main {
|
|||||||
constructor(source: any = {}) {
|
constructor(source: any = {}) {
|
||||||
if ('string' === typeof source) source = JSON.parse(source);
|
if ('string' === typeof source) source = JSON.parse(source);
|
||||||
this.enabled = source["enabled"];
|
this.enabled = source["enabled"];
|
||||||
|
this.type = source["type"];
|
||||||
|
this.transport = source["transport"];
|
||||||
this.host = source["host"];
|
this.host = source["host"];
|
||||||
this.port = source["port"];
|
this.port = source["port"];
|
||||||
|
this.com_port = source["com_port"];
|
||||||
|
this.baud = source["baud"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export class POTAUnmatched {
|
export class POTAUnmatched {
|
||||||
|
|||||||
Reference in New Issue
Block a user