feat: relay auto-control by frequency / band (PstRotator-style)
Automatically switches the Station Control relay boards from the rig's current frequency / band. Each relay carries one rule: off (manual), a frequency window (ON inside [lo,hi] kHz, OFF outside), or a set of bands (ON on those bands, OFF elsewhere). Evaluated on every CAT frequency/band change; a relay is only switched when its desired state actually changed, so tuning within a range doesn't hammer the board. A cached atomic flag keeps the CAT hot path a no-op when the feature is off (important during FT8 slice churn). Saving re-applies from the live frequency so a changed rule takes effect immediately. New Settings → Hardware → Relay auto-control section: master enable plus a per-relay mode (Off / Frequency / Band) with kHz range inputs or band chips, per configured relay board. i18n EN + FR. Azimuth/Time modes (the other two PstRotator tabs) are left for later.
This commit is contained in:
@@ -2392,6 +2392,61 @@ export namespace main {
|
||||
this.last60 = source["last60"];
|
||||
}
|
||||
}
|
||||
export class RelayAutoRule {
|
||||
device_id: string;
|
||||
relay: number;
|
||||
mode: string;
|
||||
freq_lo_khz: number;
|
||||
freq_hi_khz: number;
|
||||
bands: string[];
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new RelayAutoRule(source);
|
||||
}
|
||||
|
||||
constructor(source: any = {}) {
|
||||
if ('string' === typeof source) source = JSON.parse(source);
|
||||
this.device_id = source["device_id"];
|
||||
this.relay = source["relay"];
|
||||
this.mode = source["mode"];
|
||||
this.freq_lo_khz = source["freq_lo_khz"];
|
||||
this.freq_hi_khz = source["freq_hi_khz"];
|
||||
this.bands = source["bands"];
|
||||
}
|
||||
}
|
||||
export class RelayAutoConfig {
|
||||
enabled: boolean;
|
||||
rules: RelayAutoRule[];
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new RelayAutoConfig(source);
|
||||
}
|
||||
|
||||
constructor(source: any = {}) {
|
||||
if ('string' === typeof source) source = JSON.parse(source);
|
||||
this.enabled = source["enabled"];
|
||||
this.rules = this.convertValues(source["rules"], RelayAutoRule);
|
||||
}
|
||||
|
||||
convertValues(a: any, classs: any, asMap: boolean = false): any {
|
||||
if (!a) {
|
||||
return a;
|
||||
}
|
||||
if (a.slice && a.map) {
|
||||
return (a as any[]).map(elem => this.convertValues(elem, classs));
|
||||
} else if ("object" === typeof a) {
|
||||
if (asMap) {
|
||||
for (const key of Object.keys(a)) {
|
||||
a[key] = new classs(a[key]);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
return new classs(a);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
export class RotatorHeading {
|
||||
enabled: boolean;
|
||||
ok: boolean;
|
||||
|
||||
Reference in New Issue
Block a user