radio: Opa's update - Haagse ronde on scanner 1-3, QO-100 net (weekend reminder), antenna tip
Deploy production / deploy (push) Successful in 1m24s

- data (scripts/radio-2026-10-27-opa.sql): 145.450 in bank 1 ch 3 (ISS APRS UHF moved to ch 7),
  NL/EN notes for the Haagse ronde (scanner, not the WebSDR: trolls), new QO-100 satellietronde
  (daily 09:30, 10489.700 USB) with its reminder on Sat/Sun only
- migration: radio.nets.remind_days (null = every day of the net); scripts/radio.ts honours it,
  and `upcoming [hours]` prints the day too
- links: BATC/Goonhilly QO-100 WebSDR (via Opa, 27 Oct 2026); PI1DFT note about trolls
- Radioweetjes: Haagse ronde on the scanner, QO-100 net, magnetic antenna on a radiator
This commit is contained in:
stan committed 2026-10-27 10:34:13 +00:00
1 parent 2c8d1bd881
commit c175c25615
7 files changed
+45930 -12

No files matched your search

+49
View File
@@ -0,0 +1,49 @@
-- One-off data update from Opa (27 Oct 2026). Idempotent; run with psql -v ON_ERROR_STOP=1.
BEGIN;
-- 1) Haagse ronde in scanner bank 1, channel 3 (Opa's own layout). The ISS APRS UHF memory that
-- sat there moves to the first free bank-1 channel (7).
UPDATE radio.channels SET channel = 7, updated_at = now()
WHERE channel = 3
AND frequency_id <> (SELECT id FROM radio.frequencies WHERE freq_hz = 145450000 AND name = 'Haagse ronde')
AND NOT EXISTS (SELECT 1 FROM radio.channels WHERE channel = 7);
INSERT INTO radio.channels (channel, frequency_id, alpha_tag)
SELECT 3, id, 'HAAGSE RONDE' FROM radio.frequencies WHERE freq_hz = 145450000 AND name = 'Haagse ronde'
ON CONFLICT (channel) DO UPDATE SET frequency_id = excluded.frequency_id, alpha_tag = excluded.alpha_tag, updated_at = now();
UPDATE radio.frequencies SET notes =
'Haagse 2m-ronde, werkdagen 11:00. Luister op de scanner, bank 1 kanaal 3. Opa raadt de WebSDR voor deze ronde niet meer aan: trollen verstoren hem daar. / '
|| 'The Hague 2 m net, weekdays 11:00. Listen on the scanner, bank 1 channel 3. Opa no longer recommends the WebSDR for this net: trolls disrupt it there.',
updated_at = now()
WHERE freq_hz = 145450000 AND name = 'Haagse ronde';
UPDATE radio.nets SET notes =
'Luister op de scanner, bank 1 kanaal 3. Opa raadt de WebSDR voor deze ronde niet meer aan: trollen verstoren hem daar. Opa corrigeerde 145.350 naar 145.450. / '
|| 'Listen on the scanner, bank 1 channel 3. Opa no longer recommends the WebSDR for this net: trolls disrupt it there. Opa corrected 145.350 to 145.450.',
updated_at = now()
WHERE name = 'Haagse ronde';
-- 2) QO-100 satellite net (Dutch hams), daily 09:30 Europe/Amsterdam. Inserted with the reminder
-- off; section 3 turns it on for weekends only once the remind_days migration is in.
INSERT INTO radio.frequencies (freq_hz, mode, band, name, location, notes, tags, source)
VALUES (10489700000, 'USB', 'ham', 'QO-100 satellietronde', 'Satelliet QO-100 (Es''hail-2), smalband-transponder',
'Nederlandse zendamateurs, dagelijks 09:30. Niet met de handscanner: luister via de BATC/Goonhilly QO-100 WebSDR https://eshail.batc.org.uk/nb/ / '
|| 'Dutch hams, daily 09:30. Not on the handheld scanner: listen on the BATC/Goonhilly QO-100 WebSDR.',
'{satellite,qo-100,websdr}', 'Opa, 27 Oct 2026')
ON CONFLICT (freq_hz, name) DO NOTHING;
INSERT INTO radio.nets (name, frequency_id, days, times, kind, notes, remind, active, sort_order)
SELECT 'QO-100 satellietronde', f.id, '{1,2,3,4,5,6,7}', '{09:30}', 'net',
'Nederlandse zendamateurs via satelliet QO-100. Luister via de QO-100 WebSDR van BATC/Goonhilly: https://eshail.batc.org.uk/nb/ / '
|| 'Dutch hams via the QO-100 satellite. Listen on the BATC/Goonhilly QO-100 WebSDR.',
false, true, 15
FROM radio.frequencies f
WHERE f.freq_hz = 10489700000 AND f.name = 'QO-100 satellietronde'
AND NOT EXISTS (SELECT 1 FROM radio.nets WHERE name = 'QO-100 satellietronde');
-- 3) Stan approved the QO-100 reminder for Saturday and Sunday only (ping 09:20). Needs the
-- 20261027103329_radio_net_remind_days migration.
UPDATE radio.nets SET remind = true, remind_days = '{6,7}', updated_at = now()
WHERE name = 'QO-100 satellietronde';
COMMIT;
+13 -5
View File
@@ -5,7 +5,7 @@
* passes over Gouda into radio.iss_passes (daily timer)
* bun scripts/radio.ts remind ntfy reminder 10 minutes before each net (remind = true) and
* each ISS pass with max elevation >= 10 deg (every-minute timer)
* bun scripts/radio.ts upcoming print what the next 24 h of reminders would be (no sending)
* bun scripts/radio.ts upcoming [hours] print the reminders due in the next 24 h (no sending)
*
* Reminders go to RADIO_NTFY_URL (an ntfy topic URL, optional RADIO_NTFY_TOKEN), passed in with
* `docker exec --env-file ~/.config/radio.env`. radio.reminders makes every reminder fire once.
@@ -19,6 +19,7 @@ import {
QUIET_HOURS,
REMIND_MINUTES,
compass,
fmtDay,
fmtTime,
formatFreq,
inQuiet,
@@ -197,15 +198,21 @@ type Due = {
tags: string[];
};
/** The net's days that get a reminder: remind_days (when set) narrows the schedule. */
function remindDays(days: unknown[], only: unknown[] | null): number[] {
const all = days.map(Number);
return only ? all.filter((d) => only.map(Number).includes(d)) : all;
}
async function due(from: Date, to: Date): Promise<Due[]> {
const out: Due[] = [];
const nets = await sql`SELECT n.id, n.name, n.days, n.times, n.active, n.notes,
const nets = await sql`SELECT n.id, n.name, n.days, n.remind_days, n.times, n.active, n.notes,
f.freq_hz::float8 AS hz, f.mode, f.marine_ch
FROM radio.nets n LEFT JOIN radio.frequencies f ON f.id = n.frequency_id
WHERE n.remind AND n.active`;
for (const n of nets) {
for (const at of occurrences(
{ id: n.id, days: n.days.map(Number), times: n.times },
{ id: n.id, days: remindDays(n.days, n.remind_days), times: n.times },
from,
to
)) {
@@ -264,10 +271,11 @@ try {
else if (mode === 'remind') await remind();
else if (mode === 'upcoming') {
const now = new Date();
const hours = Number(process.argv[3] ?? 24);
console.log(`quiet hours: ${QUIET?.label ?? 'off'} (Europe/Amsterdam, by send time)`);
for (const r of await due(now, new Date(now.getTime() + 86_400_000)))
for (const r of await due(now, new Date(now.getTime() + hours * 3_600_000)))
console.log(
`${quiet(r.at) ? 'QUIET-SKIP' : 'SEND '} at ${fmtTime(sendAt(r.at))} ${r.kind}: ${r.title}`
`${quiet(r.at) ? 'QUIET-SKIP' : 'SEND '} at ${fmtDay(sendAt(r.at))} ${fmtTime(sendAt(r.at))} ${r.kind}: ${r.title}`
);
} else throw new Error(`unknown mode ${mode} (iss | remind | upcoming)`);
} finally {