All checks were successful
Deploy production / deploy (push) Successful in 1m20s
179 lines
4.6 KiB
TypeScript
179 lines
4.6 KiB
TypeScript
// One-off data fill for scanner banks 1-3 (ham + ISS). Idempotent: reuses a frequency with the
|
|
// same freq_hz + name, and only fills empty channels.
|
|
import postgres from 'postgres';
|
|
const c = postgres(process.env.DB_URL!, { prepare: false, onnotice: () => {} });
|
|
const ARISS = 'ARISS https://www.ariss.org/contact-the-iss.html + status page (7 Oct 2026)';
|
|
const RDI =
|
|
'RDI repeater list via elinek.nl, cross-checked with nl.wikipedia Lijst van amateurrelaiszenders';
|
|
type F = {
|
|
ch: number;
|
|
hz: number;
|
|
mode: string;
|
|
name: string;
|
|
tag: string;
|
|
loc?: string;
|
|
notes: string;
|
|
tags: string[];
|
|
src: string;
|
|
existing?: number;
|
|
};
|
|
const rows: F[] = [
|
|
{
|
|
ch: 1,
|
|
hz: 145_800_000,
|
|
mode: 'NFM',
|
|
name: 'ISS voice downlink (ARISS)',
|
|
tag: 'ISS VOICE/SSTV',
|
|
notes: '',
|
|
tags: [],
|
|
src: '',
|
|
existing: 330
|
|
},
|
|
{
|
|
ch: 2,
|
|
hz: 437_800_000,
|
|
mode: 'FM',
|
|
name: 'ISS FM repeater downlink',
|
|
tag: 'ISS RPT DN',
|
|
notes:
|
|
'Cross-band voice repeater (NA1SS): uplink 145.990 MHz CTCSS 67 Hz, downlink 437.800. Allow ±10 kHz Doppler.',
|
|
tags: ['iss', 'satellite', '70cm'],
|
|
src: ARISS
|
|
},
|
|
{
|
|
ch: 3,
|
|
hz: 437_825_000,
|
|
mode: 'FM',
|
|
name: 'ISS APRS digipeater (UHF, active)',
|
|
tag: 'ISS APRS UHF',
|
|
notes:
|
|
'APRS 1200 bd packet; ARISS status says APRS is currently active here (RS0ISS). Decode with software; on the scanner you hear bursts.',
|
|
tags: ['iss', 'satellite', 'aprs', '70cm'],
|
|
src: ARISS
|
|
},
|
|
{
|
|
ch: 4,
|
|
hz: 145_825_000,
|
|
mode: 'FM',
|
|
name: 'ISS APRS digipeater (VHF)',
|
|
tag: 'ISS APRS VHF',
|
|
notes: 'Usual worldwide ISS packet frequency (1200 bd APRS); currently moved to 437.825.',
|
|
tags: ['iss', 'satellite', 'aprs', '2m'],
|
|
src: ARISS
|
|
},
|
|
{
|
|
ch: 5,
|
|
hz: 437_550_000,
|
|
mode: 'FM',
|
|
name: 'ISS SSTV downlink (events)',
|
|
tag: 'ISS SSTV UHF',
|
|
notes: 'SSTV events (Robot36), announced by ARISS. Decode with an SSTV app.',
|
|
tags: ['iss', 'satellite', 'sstv', '70cm'],
|
|
src: ARISS
|
|
},
|
|
{
|
|
ch: 6,
|
|
hz: 144_800_000,
|
|
mode: 'FM',
|
|
name: 'APRS (Europe, terrestrial)',
|
|
tag: 'APRS EU',
|
|
notes: 'IARU Region 1 APRS frequency, 1200 bd packet.',
|
|
tags: ['aprs', '2m'],
|
|
src: 'IARU Region 1 VHF band plan'
|
|
},
|
|
{
|
|
ch: 51,
|
|
hz: 145_500_000,
|
|
mode: 'FM',
|
|
name: '2 m FM calling',
|
|
tag: '2M CALL',
|
|
notes: 'FM simplex calling channel (V40).',
|
|
tags: ['calling', '2m'],
|
|
src: 'IARU Region 1 VHF band plan'
|
|
},
|
|
{
|
|
ch: 52,
|
|
hz: 433_500_000,
|
|
mode: 'FM',
|
|
name: '70 cm FM calling',
|
|
tag: '70CM CALL',
|
|
notes: 'FM simplex calling channel (U280).',
|
|
tags: ['calling', '70cm'],
|
|
src: 'IARU Region 1 UHF band plan'
|
|
},
|
|
{
|
|
ch: 53,
|
|
hz: 145_450_000,
|
|
mode: 'NFM',
|
|
name: 'Haagse ronde',
|
|
tag: 'HAAGSE RONDE',
|
|
notes: '',
|
|
tags: [],
|
|
src: '',
|
|
existing: 328
|
|
},
|
|
...(
|
|
[
|
|
[
|
|
101,
|
|
430_225_000,
|
|
'PI2SWK',
|
|
'Gouda',
|
|
'431.825',
|
|
'88.5',
|
|
'Also pi2swk.nl (Goudse ronde, EchoLink 669316).'
|
|
],
|
|
[102, 145_750_000, 'PI3RAZ', 'Zoetermeer', '145.150', '88.5', ''],
|
|
[103, 145_675_000, 'PI3RTD', 'Rotterdam', '145.075', '88.5', ''],
|
|
[104, 430_300_000, 'PI2RTD', 'Rotterdam', '431.900', '88.5', ''],
|
|
[105, 430_087_500, 'PI1DFT', 'Delft', '431.6875', '88.5', 'Same club as WebSDR PI1DFT.'],
|
|
[106, 430_350_000, 'PI2HGL', 'Den Haag', '431.950', '88.5', ''],
|
|
[107, 430_050_000, 'PI2LDN', 'Leiden', '431.650', '88.5', ''],
|
|
[
|
|
108,
|
|
145_575_000,
|
|
'PI3UTR',
|
|
'IJsselstein',
|
|
'144.975',
|
|
'77',
|
|
'Regional, wide coverage (Utrecht/Hilversum TX).'
|
|
]
|
|
] as const
|
|
).map(([ch, hz, call, loc, inp, tone, extra]) => ({
|
|
ch,
|
|
hz,
|
|
mode: 'FM',
|
|
name: `${call} repeater ${loc}`,
|
|
tag: `${call} ${loc}`.slice(0, 16),
|
|
loc,
|
|
notes: `FM repeater output; input ${inp} MHz, CTCSS ${tone} Hz. ${extra}`.trim(),
|
|
tags: ['repeater', hz < 200_000_000 ? '2m' : '70cm'],
|
|
src: RDI
|
|
}))
|
|
];
|
|
let added = 0,
|
|
set = 0;
|
|
for (const r of rows) {
|
|
let id = r.existing;
|
|
if (!id) {
|
|
const [f] =
|
|
await c`SELECT id FROM radio.frequencies WHERE freq_hz = ${r.hz} AND name = ${r.name}`;
|
|
id = f?.id;
|
|
if (!id) {
|
|
[{ id }] =
|
|
await c`INSERT INTO radio.frequencies ${c({ freq_hz: r.hz, mode: r.mode, band: 'ham', name: r.name, location: r.loc ?? null, notes: r.notes, tags: r.tags, source: r.src })} RETURNING id`;
|
|
added++;
|
|
}
|
|
}
|
|
const ins =
|
|
await c`INSERT INTO radio.channels ${c({ channel: r.ch, frequency_id: id, alpha_tag: r.tag.slice(0, 16) })} ON CONFLICT (channel) DO NOTHING`;
|
|
set += ins.count;
|
|
}
|
|
console.log(JSON.stringify({ frequenciesAdded: added, channelsSet: set }));
|
|
console.log(
|
|
JSON.stringify(
|
|
await c`SELECT (SELECT count(*)::int FROM radio.frequencies) freqs, (SELECT count(*)::int FROM radio.channels) chans, (SELECT count(*)::int FROM radio.channels WHERE channel <= 150) b123`
|
|
)
|
|
);
|
|
await c.end();
|