From 03000708b6fdbcf47e62a0fc190138226c5128fc Mon Sep 17 00:00:00 2001 From: Seth Freiberg Date: Sun, 14 Jun 2026 16:02:36 -0400 Subject: [PATCH] chore: baseline existing CI-V suite before RepeaterBook integration --- ...6-06-14-144031-id5100-civ-control-suite.md | 172 +++ .gitignore | 5 + DECISIONS.md | 35 + README.md | 72 + civ.py | 95 ++ civ_probe.py | 135 ++ cli.py | 93 ++ .../2026-06-14-repeaterbook-integration.md | 852 +++++++++++ ...6-06-14-repeaterbook-integration-design.md | 201 +++ panel.html | 279 ++++ radio.py | 158 +++ repeaterbook/RB_2606141409.csv | 1259 +++++++++++++++++ server.py | 117 ++ test_civ.py | 77 + 14 files changed, 3550 insertions(+) create mode 100644 .claude/handoffs/2026-06-14-144031-id5100-civ-control-suite.md create mode 100644 .gitignore create mode 100644 DECISIONS.md create mode 100644 README.md create mode 100644 civ.py create mode 100755 civ_probe.py create mode 100755 cli.py create mode 100644 docs/superpowers/plans/2026-06-14-repeaterbook-integration.md create mode 100644 docs/superpowers/specs/2026-06-14-repeaterbook-integration-design.md create mode 100644 panel.html create mode 100644 radio.py create mode 100644 repeaterbook/RB_2606141409.csv create mode 100644 server.py create mode 100644 test_civ.py diff --git a/.claude/handoffs/2026-06-14-144031-id5100-civ-control-suite.md b/.claude/handoffs/2026-06-14-144031-id5100-civ-control-suite.md new file mode 100644 index 0000000..5caa05c --- /dev/null +++ b/.claude/handoffs/2026-06-14-144031-id5100-civ-control-suite.md @@ -0,0 +1,172 @@ +# Handoff: ID-5100 CI-V control suite (library + CLI + web panel) + +## Session Metadata +- Created: 2026-06-14 14:40:31 +- Project: /home/claude/bin/id5100 +- Branch: [not a git repo — ~/bin is not under git] +- Session duration: ~1 session + +### Recent Commits (for context) + - [not a git repo — no commits] + +## Handoff Chain + +- **Continues from**: None (fresh start) +- **Supersedes**: None + +> This is the first handoff for this task. + +## Current State Summary + +Built a complete software control layer for Seth's ICOM ID-5100 mobile transceiver +over CI-V, from nothing to a working web control panel, in one session. Started by +verifying the hardware link (RT Systems USB-29A cable into the radio's [SP2] jack), +then built a pure-stdlib codec, a serial transport, a CLI, and an industrial-themed +web panel. **Everything is verified against the live radio** — reads, writes, and the +UI screenshot. The web server is running now and reachable on the LAN. The project is +in a clean, finished-MVP state; remaining items are optional enhancements, not gaps. + +## Codebase Understanding + +### Architecture Overview + +Three clean layers, each a front-end on the one below: +- **Codec** (`civ.py`) — pure functions, no I/O: BCD freq/level encode-decode, CI-V + frame build/parse. Fully unit-tested (11 tests). +- **Transport** (`radio.py`) — `Radio` class over pure-stdlib `termios` (no pyserial). + get/set frequency, mode, volume, squelch level, S-meter, squelch status. +- **Front-ends** — `cli.py` (argparse) and `server.py` + `panel.html` (web). Both just + call `radio.Radio`. + +### Critical Files + +| File | Purpose | Relevance | +|------|---------|-----------| +| `civ.py` | Pure CI-V codec (BCD, frames) | Core; change here = re-run test_civ.py | +| `radio.py` | Serial transport + `Radio` class | All control flows through this | +| `cli.py` | CLI front end | `./cli.py status` etc. | +| `server.py` | Web panel HTTP server + JSON API | Holds the serial port while running | +| `panel.html` | Instrument-panel UI (one self-contained file) | Amber VFD aesthetic | +| `test_civ.py` | 11 codec unit tests | `python3 -m unittest test_civ` | +| `civ_probe.py` | One-shot link probe | Quick "is the radio alive" check | +| `README.md`, `DECISIONS.md` | Docs + decision log | Read first when resuming | + +### Key Patterns Discovered + +- **Verified link params:** `/dev/ttyUSB0`, **9600 baud**, radio CI-V address **0x8C**, + controller address 0xE0. +- **Bus echo:** the radio echoes your TX frame before its reply; `transact()` filters + frames whose `frm != RADIO_ADDR` (0x8C) to skip the echo. +- **Two BCD byte orders on the same radio:** frequency is 5-byte **little-endian** BCD; + levels/meters are 2-byte **big-endian** BCD (128 -> `01 28`). Pinned by unit tests. +- **Mode FM = 0x05** confirmed empirically (radio returned `05 01`). + +## Work Completed + +### Tasks Finished + +- [x] Verified PC<->radio CI-V link (read VFO = 147.300000 MHz) +- [x] TDD'd pure codec `civ.py` (11 tests green, grounded in real capture) +- [x] Built transport `radio.py`, ground-truthed all reads + write path on live radio +- [x] Optimized `transact()` early-return (status poll ~3.6s -> ~0.2s) +- [x] Built CLI `cli.py` (status/freq/mode/vol/sql/smeter) +- [x] Built web panel `server.py` + `panel.html`, verified via headless screenshot + control POST +- [x] Added `ID-5100 CI-V` row to ~/bin/CLAUDE.md projects table (backed up first) +- [x] Wrote README.md + DECISIONS.md + +### Files Modified + +| File | Changes | Rationale | +|------|---------|-----------| +| /home/claude/bin/CLAUDE.md | +1 projects-table row | Register the project (backup: .backup/CLAUDE.md-1781461768) | +| (all id5100/* files) | Created this session | The deliverable | + +### Decisions Made + +| Decision | Options Considered | Rationale | +|----------|-------------------|-----------| +| Pure stdlib `termios` | pyserial | System Python is PEP-668 locked; --break-system-packages violates escalation-brake rule | +| stdlib `http.server` for web | Flask/FastAPI | Keep no-deps promise | +| Early-return `transact()` | fixed timeout | Makes ~1 Hz live S-meter polling viable | +| Industrial VFD aesthetic | generic dashboard | Matches radio-gear domain + Sethian dark/orange brand | +| Reject full headless-head replica | reverse-engineer head bus | Proprietary/undocumented; CI-V covers operating functions | + +(Full list in DECISIONS.md.) + +## Pending Work + +## Immediate Next Steps + +1. **(Optional) systemd user unit for `server.py`** — it's currently a bare background + process (won't survive reboot/logout). This is the most likely next ask. +2. **(Optional) Vendor the web fonts locally** — `panel.html` pulls DSEG7 (jsdelivr) + + Saira/Chivo Mono (Google Fonts) from CDNs; offline it falls back to monospace. +3. **(Optional) Verify DV mode (0x17) on the live radio** — currently from the generic + ICOM table, flagged not-trusted. Test `./cli.py mode dv` and confirm the radio ACKs. + +### Blockers/Open Questions + +- [ ] None blocking. Open question: does Seth want this behind Caddy with a subdomain + (e.g. `radio.sethpc.xyz`) like his other services? Not discussed. + +### Deferred Items + +- Full software control-head replica (proprietary head bus) — rejected, see DECISIONS.md. +- RS-MS1A data-jack protocol (D-STAR DR routing / callsign / messaging) — out of scope + for this CI-V layer; separate effort if wanted. +- HA/MQTT bridge — offered, not chosen this session. + +## Context for Resuming Agent + +## Important Context + +The whole suite is **verified against real hardware**, not just written. If resuming, +you can trust the link params and the codec. The radio is a physical device on Seth's +desk — **set-commands change real radio state**, so prefer no-op writes (write current +value back) when testing the write path, as was done here. The only process that can +hold `/dev/ttyUSB0` is one at a time: **stop `server.py` before running `cli.py`** or +the probe, and vice versa. + +### Assumptions Made + +- The radio stays on `/dev/ttyUSB0` (single USB-serial device; confirmed by Seth). +- CI-V baud stays 9600 (Seth set this in the radio menu this session). +- The PC hosting all this is steel141 (192.168.0.141). + +### Potential Gotchas + +- **Don't `--break-system-packages`** — stdlib-only is a deliberate decision. +- **Bus echo** will confuse any new raw-serial code; reuse `civ.parse_frames` + the + `frm == RADIO_ADDR` filter. +- **DV=0x17 is unverified** — don't present `set_mode('dv')` as trusted yet. +- The web panel needs internet for the nice fonts (graceful monospace fallback otherwise). + +## Environment State + +### Tools/Services Used + +- RT Systems USB-29A cable (FTDI), enumerates as `/dev/serial/by-id/usb-RT_Systems_CT29A_Radio_Cable_RT90581N-if00-port0` -> `/dev/ttyUSB0` +- `claude` user is in `dialout` group (serial access OK) +- chromium (headless) used for the verification screenshot +- Python 3.13 (system, PEP-668 externally-managed) + +### Active Processes + +- **`server.py --port 8550` is RUNNING** (was PID 380991 this session) at + **http://192.168.0.141:8550/** (bound 0.0.0.0, LAN/phone reachable). Log at + `id5100/.server.log`. It holds `/dev/ttyUSB0`. Kill with `pkill -f "server.py --port 8550"`. + +### Environment Variables + +- None specific to this project. (Homelab-wide: `HOMELAB_PASSWORD` exists but unused here.) + +## Related Resources + +- `id5100/README.md` — usage + verified-facts +- `id5100/DECISIONS.md` — decision log incl. Deferred/Rejected +- `~/bin/CLAUDE.md` — projects table entry +- ICOM ID-5100 full manual CI-V section (p.305) — frame format / address 0x8C + +--- + +**Security Reminder**: Before finalizing, run `validate_handoff.py` to check for accidental secret exposure. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..958a40c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.env +.backup/ +.server.log +__pycache__/ +*.pyc diff --git a/DECISIONS.md b/DECISIONS.md new file mode 100644 index 0000000..ac8048e --- /dev/null +++ b/DECISIONS.md @@ -0,0 +1,35 @@ +# id5100 — Decisions + +Format: `YYYY-MM-DD: ` + +- 2026-06-14: Pure-stdlib `termios` instead of pyserial — system Python is PEP-668 + externally-managed; per the escalation-brake rule, `--break-system-packages` for + one dependency is the wrong trade. `termios` is zero-install and reusable. +- 2026-06-14: Layered as codec (`civ.py`) / transport (`radio.py`) / CLI (`cli.py`) + — the codec is pure and unit-testable; web UI / HA-MQTT front ends bolt onto the + transport without touching byte plumbing. +- 2026-06-14: TDD the codec against the real probe capture (`00 00 30 47 01` ↔ + 147.300000 MHz) — gives a hardware-true vector, not a made-up one. +- 2026-06-14: Cable lands on **[SP2]** (= CI-V), 9600 baud, addr 0x8C — verified + live, not assumed. + +- 2026-06-14: Web panel = stdlib `http.server` + single `panel.html`, no framework + — keeps the no-deps promise; the UI is one self-contained file. One shared `Radio` + guarded by a lock (CI-V is half-duplex; concurrent transactions would interleave). +- 2026-06-14: `transact()` returns as soon as the radio's reply frame parses instead + of always burning the full timeout — dropped a full status poll from ~3.6s to ~0.2s, + making a ~1 Hz live S-meter poll viable. +- 2026-06-14: Aesthetic = industrial instrument faceplate (amber VFD via DSEG7 font, + LED S-meter, illuminated mode buttons) — matches the radio-gear domain and the + Sethian dark/orange brand. Verified by headless screenshot. + +## Deferred / Rejected + +- **Full software control-head replica** — rejected: the detachable head talks a + proprietary, undocumented bus to the main unit; CI-V exposes operating functions + only (no menu/LCD mirror). Not worth reverse-engineering. +- **pyserial** — rejected (see above). +- **DV mode set** — deferred: 0x17 unverified on this radio; don't ship set_mode('dv') + as trusted until confirmed against the manual's CI-V table or the live rig. +- **RS-MS1A data-jack protocol (D-STAR DR/callsign/messaging)** — out of scope for + this CI-V layer; separate effort if wanted. diff --git a/README.md b/README.md new file mode 100644 index 0000000..e9ef7c5 --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ +# id5100 — CI-V control for the ICOM ID-5100 + +Software control layer for the ID-5100 mobile transceiver over CI-V, via the +RT Systems USB-29A cable (FTDI) plugged into the radio's **[SP2]** jack. + +- **Verified link:** `/dev/ttyUSB0`, **9600 baud**, radio CI-V address **0x8C**. +- **No dependencies** — pure stdlib (`termios`), no pyserial. + +## Layers + +| File | Role | Tested by | +|------|------|-----------| +| `civ.py` | Pure CI-V codec: BCD freq/level encode-decode, frame build/parse | `test_civ.py` (11 unit tests) | +| `radio.py` | Serial transport + high-level `Radio` class (get/set freq, mode, vol, sql, smeter) | live-radio integration | +| `cli.py` | Command-line front end | live-radio integration | +| `server.py` | Web control-panel server (stdlib `http.server` + JSON API) | live-radio integration | +| `panel.html` | Instrument-panel web UI (amber VFD, S-meter, mode/level controls) | headless screenshot | +| `civ_probe.py` | One-shot link probe (read VFO frequency) | — | + +## CLI + +```bash +./cli.py status # freq, mode, volume, squelch, s-meter at a glance +./cli.py freq # read VFO (MHz) +./cli.py freq 146.52 # set VFO to 146.520 MHz +./cli.py mode fm # set mode: lsb/usb/am/cw/fm/dv +./cli.py vol 30 # set AF volume 0-255 (read with no arg) +./cli.py sql 60 # set squelch level 0-255 +./cli.py smeter # read S-meter 0-255 +# global: --port /dev/ttyUSB0 --baud 9600 +``` + +## Web panel + +```bash +python3 server.py # http://:8550/ (binds 0.0.0.0 -> phone-reachable) +# --port 8550 --serial /dev/ttyUSB0 --baud 9600 +``` + +Holds the serial port for its lifetime, so **don't run `cli.py` while the server +is up** (one process owns `/dev/ttyUSB0`). The page polls `/api/status` ~1/s for +live frequency, mode, S-meter, squelch, and levels; controls POST to +`/api/{freq,mode,vol,sql}`. + +## Library + +```python +from radio import Radio +with Radio("/dev/ttyUSB0", 9600) as r: + r.get_frequency() # -> Hz + r.set_frequency(146_520_000) + r.get_mode() # -> ("FM", 0x05) + r.set_volume(30) +``` + +## Tests + +```bash +python3 -m unittest test_civ -v +``` + +## Gotchas / verified facts + +- **[SP2] *is* the CI-V port** on the ID-5100 (doubles as 2nd speaker jack). +- **Bus echo:** the radio echoes your TX frame before replying; `transact()` + filters frames where `frm != RADIO_ADDR`. +- **Frequency BCD is little-endian; level/meter BCD is big-endian** (`128 -> 01 28`). +- **Mode FM = 0x05** confirmed empirically. `DV = 0x17` is from the generic + ICOM table and **not yet verified on this radio** — confirm before relying on it. +- Scope is CI-V (operate the radio). D-STAR DR routing / callsign entry live in + the separate RS-MS1A data-jack protocol, not here. +``` diff --git a/civ.py b/civ.py new file mode 100644 index 0000000..984b2da --- /dev/null +++ b/civ.py @@ -0,0 +1,95 @@ +""" +Pure CI-V codec for the ICOM ID-5100 — no I/O, no dependencies. + +CI-V frame: FE FE [sub] [data...] FD +All multi-byte numeric fields are BCD. Frequency is 5-byte little-endian BCD; +levels/meters are 2-byte big-endian BCD in the range 0000..0255. +""" +from collections import namedtuple + +RADIO_ADDR = 0x8C # ID-5100 default CI-V address +CTRL_ADDR = 0xE0 # this controller's address +PREAMBLE = b"\xFE\xFE" +EOM = 0xFD + +# Command bytes (generic ICOM CI-V; verified subset for the ID-5100) +CMD_READ_FREQ = 0x03 +CMD_READ_MODE = 0x04 +CMD_SET_FREQ = 0x05 +CMD_SET_MODE = 0x06 +CMD_LEVEL = 0x14 # sub 0x01 = AF (volume), 0x03 = squelch level +CMD_METER = 0x15 # sub 0x01 = squelch status, 0x02 = S-meter +SUB_AF = 0x01 +SUB_SQL_LEVEL = 0x03 +SUB_SQL_STATUS = 0x01 +SUB_SMETER = 0x02 + +Frame = namedtuple("Frame", "to frm cn data") + + +def freq_to_bcd(hz): + """Hz -> 5-byte little-endian BCD.""" + digits = f"{hz:010d}" # 10 decimal digits (up to 9.999 GHz) + out = bytearray() + # pairs from least significant; byte0 holds the lowest two digits + for i in range(0, 10, 2): + hi = digits[8 - i] + lo = digits[9 - i] + out.append((int(hi) << 4) | int(lo)) + return bytes(out) + + +def bcd_to_freq(data): + """5-byte little-endian BCD -> Hz.""" + hz = 0 + for i, byte in enumerate(data[:5]): + ones = byte & 0x0F + tens = byte >> 4 + hz += ones * (10 ** (2 * i)) + tens * (10 ** (2 * i + 1)) + return hz + + +def level_to_bcd(value): + """0..255 -> 2-byte BCD (e.g. 128 -> 01 28).""" + if not 0 <= value <= 255: + raise ValueError(f"level {value} out of range 0..255") + digits = f"{value:04d}" + return bytes([(int(digits[0]) << 4) | int(digits[1]), + (int(digits[2]) << 4) | int(digits[3])]) + + +def bcd_to_level(data): + """2-byte BCD -> int 0..255.""" + value = 0 + for byte in data[:2]: + value = value * 100 + (byte >> 4) * 10 + (byte & 0x0F) + return value + + +def build_frame(cmd, data=b"", to=RADIO_ADDR, frm=CTRL_ADDR): + """Assemble FE FE [data] FD.""" + return PREAMBLE + bytes([to, frm, cmd]) + bytes(data) + bytes([EOM]) + + +def parse_frames(buf): + """Extract complete CI-V frames from a byte buffer, skipping noise/echo. + + Returns a list of Frame(to, frm, cn, data) where `data` is everything + between the command byte and the EOM (so it includes any subcommand byte). + """ + frames = [] + i, n = 0, len(buf) + while i < n - 1: + if buf[i] == 0xFE and buf[i + 1] == 0xFE: + j = i + 2 + while j < n and buf[j] != EOM: + j += 1 + if j >= n: + break # incomplete trailing frame + inner = buf[i + 2:j] + if len(inner) >= 3: + frames.append(Frame(inner[0], inner[1], inner[2], bytes(inner[3:]))) + i = j + 1 + continue + i += 1 + return frames diff --git a/civ_probe.py b/civ_probe.py new file mode 100755 index 0000000..4fd4be8 --- /dev/null +++ b/civ_probe.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python3 +""" +ICOM ID-5100 CI-V link probe (pure stdlib, no pyserial). + +Opens the RT Systems USB-29A cable (FTDI, plugged into the radio's [SP2]/CI-V +jack), sends a "read operating frequency" CI-V frame, and decodes the reply. +A valid reply proves the PC <-> radio control link end-to-end. + +Defaults: /dev/ttyUSB0, 9600 baud, radio CI-V address 0x8C, controller 0xE0. + +Usage: + python3 civ_probe.py [PORT] [BAUD] + python3 civ_probe.py /dev/ttyUSB0 9600 +""" +import os +import sys +import time +import termios + +RADIO_ADDR = 0x8C # ID-5100 default CI-V address +CTRL_ADDR = 0xE0 # this controller's address +PREAMBLE = b"\xFE\xFE" +EOM = 0xFD + +BAUD_CONST = { + 1200: termios.B1200, 4800: termios.B4800, 9600: termios.B9600, + 19200: termios.B19200, 38400: termios.B38400, 115200: termios.B115200, +} + + +def open_port(port, baud): + fd = os.open(port, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK) + speed = BAUD_CONST.get(baud) + if speed is None: + raise ValueError(f"unsupported baud {baud}; choose one of {sorted(BAUD_CONST)}") + iflag, oflag, cflag, lflag, ispeed, ospeed, cc = termios.tcgetattr(fd) + # raw 8N1, receiver on, ignore modem control lines + iflag = 0 + oflag = 0 + lflag = 0 + cflag = termios.CS8 | termios.CREAD | termios.CLOCAL + cc = list(cc) + cc[termios.VMIN] = 0 + cc[termios.VTIME] = 0 + termios.tcsetattr(fd, termios.TCSANOW, [iflag, oflag, cflag, lflag, speed, speed, cc]) + termios.tcflush(fd, termios.TCIOFLUSH) + return fd + + +def read_for(fd, seconds): + """Collect raw bytes for `seconds`, return bytearray.""" + buf = bytearray() + deadline = time.monotonic() + seconds + while time.monotonic() < deadline: + try: + chunk = os.read(fd, 256) + except BlockingIOError: + chunk = b"" + if chunk: + buf.extend(chunk) + else: + time.sleep(0.01) + return buf + + +def split_frames(buf): + """Yield CI-V frames (FE FE ... FD), skipping leading echo/noise.""" + i = 0 + n = len(buf) + while i < n - 1: + if buf[i] == 0xFE and buf[i + 1] == 0xFE: + j = i + 2 + while j < n and buf[j] != EOM: + j += 1 + if j < n: + yield bytes(buf[i:j + 1]) + i = j + 1 + continue + i += 1 + + +def decode_freq(data): + """5-byte little-endian BCD -> Hz.""" + hz = 0 + for i, byte in enumerate(data[:5]): + ones = byte & 0x0F + tens = byte >> 4 + hz += ones * (10 ** (2 * i)) + tens * (10 ** (2 * i + 1)) + return hz + + +def main(): + port = sys.argv[1] if len(sys.argv) > 1 else "/dev/ttyUSB0" + baud = int(sys.argv[2]) if len(sys.argv) > 2 else 9600 + + print(f"Port {port} @ {baud} baud | radio 0x{RADIO_ADDR:02X} ctrl 0x{CTRL_ADDR:02X}") + fd = open_port(port, baud) + try: + # read operating frequency: FE FE 03 FD + cmd = PREAMBLE + bytes([RADIO_ADDR, CTRL_ADDR, 0x03, EOM]) + print("TX:", cmd.hex(" ")) + os.write(fd, cmd) + buf = read_for(fd, 1.0) + finally: + os.close(fd) + + if not buf: + print("RX: (nothing)") + print("\nNo bytes back. Check: SP2 jack seated, radio CI-V baud = " + f"{baud}, radio powered on. Single-device port was confirmed as this one.") + sys.exit(2) + + print("RX raw:", buf.hex(" ")) + got_freq = False + for frame in split_frames(buf): + # frame: FE FE [data...] FD + if len(frame) < 6: + continue + to, frm, cn = frame[2], frame[3], frame[4] + body = frame[5:-1] + tag = "echo" if (to == RADIO_ADDR and frm == CTRL_ADDR) else "radio->us" + print(f" frame [{tag}] to=0x{to:02X} from=0x{frm:02X} cn=0x{cn:02X} body={body.hex(' ')}") + if frm == RADIO_ADDR and cn == 0x03 and len(body) >= 5: + hz = decode_freq(body) + print(f"\n*** LINK OK -- VFO frequency: {hz/1e6:.6f} MHz ***") + got_freq = True + + if not got_freq: + print("\nGot bytes but no frequency frame. Link is alive but reply was " + "unexpected -- check baud match and CI-V address.") + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/cli.py b/cli.py new file mode 100755 index 0000000..ef70226 --- /dev/null +++ b/cli.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 +""" +id5100 — command-line control for the ICOM ID-5100 over CI-V. + + ./cli.py status show everything at a glance + ./cli.py freq read VFO frequency + ./cli.py freq 146.52 set VFO to 146.520 MHz + ./cli.py mode read mode + ./cli.py mode fm set mode (lsb/usb/am/cw/fm/dv) + ./cli.py vol [0-255] get/set AF (volume) + ./cli.py sql [0-255] get/set squelch level + ./cli.py smeter read S-meter (0-255) + +Global: --port (default /dev/ttyUSB0) --baud (default 9600) +""" +import argparse +import sys + +from radio import Radio, CIVError + + +def cmd_status(r, _): + freq = r.get_frequency() + mode, _code = r.get_mode() + print(f"freq : {freq/1e6:.5f} MHz") + print(f"mode : {mode}") + print(f"volume : {r.get_volume()}/255") + print(f"squelch: level {r.get_squelch_level()}/255, " + f"{'OPEN' if r.squelch_open() else 'closed'}") + print(f"s-meter: {r.get_smeter()}/255") + + +def cmd_freq(r, a): + if a.value is None: + print(f"{r.get_frequency()/1e6:.5f} MHz") + else: + hz = int(round(float(a.value) * 1e6)) # CLI takes MHz + r.set_frequency(hz) + print(f"set -> {r.get_frequency()/1e6:.5f} MHz") + + +def cmd_mode(r, a): + if a.value is None: + print(r.get_mode()[0]) + else: + r.set_mode(a.value) + print(f"set -> {r.get_mode()[0]}") + + +def _level_cmd(getter, setter): + def run(r, a): + if a.value is None: + print(f"{getter(r)}/255") + else: + setter(r, int(a.value)) + print(f"set -> {getter(r)}/255") + return run + + +def cmd_smeter(r, _): + print(f"{r.get_smeter()}/255") + + +def build_parser(): + p = argparse.ArgumentParser(prog="id5100", description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("--port", default="/dev/ttyUSB0") + p.add_argument("--baud", type=int, default=9600) + sub = p.add_subparsers(dest="cmd", required=True) + + sub.add_parser("status").set_defaults(func=cmd_status) + sub.add_parser("smeter").set_defaults(func=cmd_smeter) + for name, func in (("freq", cmd_freq), ("mode", cmd_mode), + ("vol", _level_cmd(Radio.get_volume, Radio.set_volume)), + ("sql", _level_cmd(Radio.get_squelch_level, Radio.set_squelch_level))): + sp = sub.add_parser(name) + sp.add_argument("value", nargs="?", default=None) + sp.set_defaults(func=func) + return p + + +def main(): + args = build_parser().parse_args() + try: + with Radio(args.port, args.baud) as r: + args.func(r, args) + except (CIVError, ValueError, OSError) as e: + print(f"error: {e}", file=sys.stderr) + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/docs/superpowers/plans/2026-06-14-repeaterbook-integration.md b/docs/superpowers/plans/2026-06-14-repeaterbook-integration.md new file mode 100644 index 0000000..7422be8 --- /dev/null +++ b/docs/superpowers/plans/2026-06-14-repeaterbook-integration.md @@ -0,0 +1,852 @@ +# RepeaterBook Integration Implementation Plan (CSV-only) + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Add a "Repeaters" feature to the ID-5100 web panel that lists nearby repeaters (from a RepeaterBook CSV export, proximity-ordered) and, on one tap, configures the radio's frequency, duplex offset, and CTCSS tone over CI-V. + +**Architecture:** Extend the existing `civ → radio → {server, panel}` layering with one focused new pure module, `repeaters.py`, that normalizes a RepeaterBook CSV into `repeaters.json` and serves rank-ordered, text-filtered results. New CI-V offset/tone commands are added to `civ.py`/`radio.py` and ground-truthed against the live radio. The panel reads only the local cache. + +**Tech Stack:** Python 3 stdlib only (`termios`, `http.server`, `csv`, `json`, `unittest`). No third-party packages. Vanilla JS/CSS in `panel.html`. + +**Data source:** `repeaterbook/RB_2606141409.csv` (1258 rows, DC-metro, RepeaterBook proximity sort). Columns: `Output Freq, Input Freq, Offset, Uplink Tone, Downlink Tone, Call, Location, County, State, Modes, Digital Access`. No lat/long → file order **is** the distance ranking. + +--- + +## Conventions for this plan + +- **Not under version control yet.** `~/bin` is not a git repo. The `git init` decision is pending; until then treat each **Commit** step as a checkpoint (stop, confirm tests green, move on). If `git init` is run inside `id5100/`, the commands work as written. +- **Back up before modifying existing files** (global safety rule). Each task that *modifies* an existing file starts with a backup step to `id5100/.backup/`. +- **Run tests from the project root:** `cd /home/claude/bin/id5100`. +- **One process owns `/dev/ttyUSB0`.** Stop `server.py` before any live-radio test (`pkill -f "server.py --port 8550"`), restart after. +- **Provisional encodings.** Offset/tone byte encodings (Tasks 1–2) are *candidates*; round-trip tests validate them now, Task 6 captures real bytes from the radio and corrects them + pins a real-capture test if they differ — same as how `freq_to_bcd` was pinned to `REAL_BCD`. + +--- + +## File structure + +| File | Create/Modify | Responsibility | +|------|---------------|----------------| +| `civ.py` | Modify | Offset/tone command constants + BCD encoders (pure) | +| `test_civ.py` | Modify | Round-trip + structure tests for new encoders | +| `repeaters.py` | Create | CSV normalize, ingest→json, load, rank-ordered search (pure + small file I/O) | +| `test_repeaters.py` | Create | normalize_csv mapping + search (rank/filter/limit) tests | +| `repeaters.json` | Create (generated) | Normalized data, produced by ingesting the CSV | +| `radio.py` | Modify | `set_duplex/set_offset/set_tone/set_tone_on` + getters + `tune_repeater` | +| `server.py` | Modify | `GET /api/repeaters`, `POST /api/tune-repeater` | +| `panel.html` | Modify | "Repeaters" card: search + rank-ordered list + per-step status | +| `README.md` | Modify | Document the feature (CSV refresh workflow) | +| `DECISIONS.md` | Modify | Record decisions/limitations | + +--- + +## Task 1: Offset BCD codec in civ.py + +**Files:** +- Modify: `civ.py` (constants after line 25; functions after `bcd_to_level`) +- Test: `test_civ.py` + +- [ ] **Step 1: Back up civ.py** + +Run: `mkdir -p .backup && cp civ.py .backup/civ.py-$(date +%s)` + +- [ ] **Step 2: Write the failing test** — add to `test_civ.py` before `if __name__`: + +```python +class TestOffsetCodec(unittest.TestCase): + # PROVISIONAL: 3-byte little-endian BCD in units of 100 Hz. + # Round-trip validated until pinned to a real capture (plan Task 6). + def test_offset_roundtrip(self): + for hz in (600_000, 5_000_000, 1_600_000, 0): + self.assertEqual(civ.bcd_to_offset(civ.offset_to_bcd(hz)), hz) + + def test_offset_is_three_bytes(self): + self.assertEqual(len(civ.offset_to_bcd(600_000)), 3) + + def test_offset_rejects_negative(self): + with self.assertRaises(ValueError): + civ.offset_to_bcd(-1) +``` + +- [ ] **Step 3: Run test to verify it fails** + +Run: `python3 -m unittest test_civ.TestOffsetCodec -v` +Expected: FAIL — `AttributeError: module 'civ' has no attribute 'offset_to_bcd'` + +- [ ] **Step 4: Add constants + implementation to civ.py** + +Constants (after line 25, the `SUB_SMETER` line): + +```python +# --- repeater config (candidate commands; verify on live radio) --- +CMD_OFFSET = 0x0D # set duplex offset frequency +CMD_DUPLEX = 0x0F # set duplex direction +DUP_SIMPLEX = 0x10 +DUP_MINUS = 0x11 +DUP_PLUS = 0x12 +CMD_TONE_PARAM = 0x1B # sub 0x00 = repeater (TX) tone frequency +SUB_RPT_TONE = 0x00 +CMD_TONE_SWITCH = 0x16 # sub 0x42 = tone encode on/off +SUB_TONE_ENC = 0x42 +``` + +Functions (after `bcd_to_level`): + +```python +def offset_to_bcd(hz): + """Duplex offset Hz -> 3-byte little-endian BCD in 100 Hz units (PROVISIONAL).""" + if hz < 0: + raise ValueError(f"offset {hz} must be >= 0") + units = round(hz / 100) + digits = f"{units:06d}" + out = bytearray() + for i in range(0, 6, 2): + out.append((int(digits[4 - i]) << 4) | int(digits[5 - i])) + return bytes(out) + + +def bcd_to_offset(data): + """3-byte little-endian BCD (100 Hz units) -> Hz (PROVISIONAL).""" + units = 0 + for i, byte in enumerate(data[:3]): + units += (byte & 0x0F) * (10 ** (2 * i)) + (byte >> 4) * (10 ** (2 * i + 1)) + return units * 100 +``` + +- [ ] **Step 5: Run test to verify it passes** + +Run: `python3 -m unittest test_civ.TestOffsetCodec -v` +Expected: PASS (3 tests) + +- [ ] **Step 6: Commit** + +```bash +git add civ.py test_civ.py +git commit -m "feat: offset BCD codec (provisional encoding)" +``` + +--- + +## Task 2: Tone BCD codec in civ.py + +**Files:** +- Modify: `civ.py` +- Test: `test_civ.py` + +- [ ] **Step 1: Back up civ.py** + +Run: `cp civ.py .backup/civ.py-$(date +%s)` + +- [ ] **Step 2: Write the failing test** — add to `test_civ.py`: + +```python +class TestToneCodec(unittest.TestCase): + # ICOM convention: CTCSS tone as 2-byte BCD of tone*10. 131.8 -> "13 18". + def test_tone_to_bcd_known(self): + self.assertEqual(civ.tone_to_bcd(88.5), b"\x08\x85") + self.assertEqual(civ.tone_to_bcd(131.8), b"\x13\x18") + self.assertEqual(civ.tone_to_bcd(100.0), b"\x10\x00") + + def test_bcd_to_tone_known(self): + self.assertAlmostEqual(civ.bcd_to_tone(b"\x13\x18"), 131.8) + self.assertAlmostEqual(civ.bcd_to_tone(b"\x08\x85"), 88.5) + + def test_tone_roundtrip(self): + for hz in (67.0, 88.5, 131.8, 146.2, 203.5): + self.assertAlmostEqual(civ.bcd_to_tone(civ.tone_to_bcd(hz)), hz) +``` + +- [ ] **Step 3: Run test to verify it fails** + +Run: `python3 -m unittest test_civ.TestToneCodec -v` +Expected: FAIL — `AttributeError: module 'civ' has no attribute 'tone_to_bcd'` + +- [ ] **Step 4: Implement in civ.py** (after the offset functions) + +```python +def tone_to_bcd(hz): + """CTCSS tone Hz -> 2-byte BCD of tone*10 (88.5 -> 08 85).""" + digits = f"{round(hz * 10):04d}" + return bytes([(int(digits[0]) << 4) | int(digits[1]), + (int(digits[2]) << 4) | int(digits[3])]) + + +def bcd_to_tone(data): + """2-byte BCD of tone*10 -> CTCSS tone Hz.""" + t = 0 + for byte in data[:2]: + t = t * 100 + (byte >> 4) * 10 + (byte & 0x0F) + return t / 10.0 +``` + +- [ ] **Step 5: Run the whole codec suite** + +Run: `python3 -m unittest test_civ -v` +Expected: PASS (17 tests: 11 original + 3 offset + 3 tone) + +- [ ] **Step 6: Commit** + +```bash +git add civ.py test_civ.py +git commit -m "feat: CTCSS tone BCD codec" +``` + +--- + +## Task 3: CSV normalizer in repeaters.py + +**Files:** +- Create: `repeaters.py` +- Test: `test_repeaters.py` + +- [ ] **Step 1: Write the failing test** — create `test_repeaters.py`: + +```python +#!/usr/bin/env python3 +"""Unit tests for repeaters.py (pure: no network, no radio). `python3 -m unittest`.""" +import unittest + +import repeaters + + +class TestNormalizeCsv(unittest.TestCase): + ROW = { + "Output Freq": "147.300000", "Input Freq": "147.90000", "Offset": "+", + "Uplink Tone": "131.8", "Downlink Tone": "131.8", "Call": "W4ABC", + "Location": "Fairfax", "County": "Fairfax", "State": "Virginia", + "Modes": "FM ", "Digital Access": "", + } + + def test_core_fields(self): + r = repeaters.normalize_csv(self.ROW, 7) + self.assertEqual(r["callsign"], "W4ABC") + self.assertAlmostEqual(r["output_mhz"], 147.300) + self.assertEqual(r["rank"], 7) + self.assertEqual(r["location"], "Fairfax, VA") + + def test_offset_sign_and_magnitude(self): + r = repeaters.normalize_csv(self.ROW, 0) + self.assertEqual(r["duplex"], "+") + self.assertAlmostEqual(r["offset_mhz"], 0.600, places=4) + + def test_negative_offset(self): + row = dict(self.ROW, **{"Input Freq": "146.700000", "Offset": "-"}) + self.assertEqual(repeaters.normalize_csv(row, 0)["duplex"], "-") + + def test_simplex(self): + row = dict(self.ROW, **{"Input Freq": "147.300000", "Offset": ""}) + self.assertEqual(repeaters.normalize_csv(row, 0)["duplex"], "simplex") + + def test_tone(self): + r = repeaters.normalize_csv(self.ROW, 0) + self.assertAlmostEqual(r["tone_hz"], 131.8) + self.assertEqual(r["tone_mode"], "ctcss") + + def test_no_tone(self): + row = dict(self.ROW); row["Uplink Tone"] = "" + r = repeaters.normalize_csv(row, 0) + self.assertIsNone(r["tone_hz"]) + self.assertEqual(r["tone_mode"], "none") + + def test_pure_dstar_is_dv(self): + row = dict(self.ROW, **{"Modes": "DSTAR "}) + self.assertEqual(repeaters.normalize_csv(row, 0)["mode"], "DV") + + def test_fm_dstar_is_fm(self): + row = dict(self.ROW, **{"Modes": "FM DSTAR "}) + self.assertEqual(repeaters.normalize_csv(row, 0)["mode"], "FM") +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `python3 -m unittest test_repeaters.TestNormalizeCsv -v` +Expected: FAIL — `ModuleNotFoundError: No module named 'repeaters'` + +- [ ] **Step 3: Create repeaters.py** + +```python +""" +Repeater directory: ingest a RepeaterBook CSV export into a normalized +repeaters.json, then load / text-search / rank it. Pure logic + small file I/O; +no radio, no network. + +CSV is RepeaterBook's proximity export (nearest-first), so file order IS the +distance ranking -> each record carries an integer `rank`. + +Normalized record schema: + callsign, location, output_mhz, offset_mhz, duplex ("+"/"-"/"simplex"), + tone_hz (or None), tone_mode ("ctcss"/"none"), mode ("FM"/"DV"), + rank (int), notes + +Usage: + python3 repeaters.py ingest repeaterbook/RB_xxxx.csv [repeaters.json] +""" +import csv +import json +import sys + +# US state -> USPS abbreviation (only the ones this export touches; extend freely) +_STATE_ABBR = { + "Virginia": "VA", "Maryland": "MD", "District of Columbia": "DC", + "Pennsylvania": "PA", "West Virginia": "WV", "Delaware": "DE", + "New Jersey": "NJ", "North Carolina": "NC", +} + + +def _f(val): + """Parse a possibly-empty numeric string to float, else None.""" + try: + return float(val) + except (TypeError, ValueError): + return None + + +def normalize_csv(row, rank): + """Map a RepeaterBook CSV row (dict) + its file rank to the internal schema.""" + out = _f(row.get("Output Freq")) + inp = _f(row.get("Input Freq")) + sign = (row.get("Offset") or "").strip() + if out is not None and inp is not None and sign in ("+", "-"): + duplex = sign + offset = round(abs(inp - out), 5) + else: + duplex, offset = "simplex", 0.0 + + tone = _f(row.get("Uplink Tone")) + city = (row.get("Location") or "").strip() + state = (row.get("State") or "").strip() + location = ", ".join(p for p in (city, _STATE_ABBR.get(state, state)) if p) + + modes = (row.get("Modes") or "").upper() + mode = "FM" if "FM" in modes else ("DV" if "DSTAR" in modes else "FM") + + return { + "callsign": (row.get("Call") or "").strip(), + "location": location, + "output_mhz": out, + "offset_mhz": offset, + "duplex": duplex, + "tone_hz": tone, + "tone_mode": "ctcss" if tone else "none", + "mode": mode, + "rank": rank, + "notes": "", + } +``` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `python3 -m unittest test_repeaters.TestNormalizeCsv -v` +Expected: PASS (8 tests) + +- [ ] **Step 5: Commit** + +```bash +git add repeaters.py test_repeaters.py +git commit -m "feat: RepeaterBook CSV row normalizer" +``` + +--- + +## Task 4: load + search in repeaters.py + +**Files:** +- Modify: `repeaters.py` +- Test: `test_repeaters.py` + +- [ ] **Step 1: Write the failing test** — add to `test_repeaters.py`: + +```python +class TestSearch(unittest.TestCase): + RECS = [ + {"callsign": "NEAR", "location": "Fairfax, VA", "mode": "FM", "rank": 0}, + {"callsign": "MID", "location": "Bethesda, MD", "mode": "DV", "rank": 5}, + {"callsign": "FAR", "location": "Norfolk, VA", "mode": "FM", "rank": 50}, + ] + + def test_rank_order_preserved(self): + out = repeaters.search(self.RECS, "", 10) + self.assertEqual([r["callsign"] for r in out], ["NEAR", "MID", "FAR"]) + + def test_text_filter_callsign_and_location(self): + self.assertEqual(len(repeaters.search(self.RECS, "norfolk", 10)), 1) + self.assertEqual(repeaters.search(self.RECS, "far", 10)[0]["callsign"], "FAR") + + def test_filter_is_case_insensitive(self): + self.assertEqual(repeaters.search(self.RECS, "BETHESDA", 10)[0]["callsign"], "MID") + + def test_limit(self): + self.assertEqual(len(repeaters.search(self.RECS, "", 2)), 2) + + +class TestLoad(unittest.TestCase): + def test_missing_file_returns_empty(self): + self.assertEqual(repeaters.load("/no/such/file.json"), []) +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `python3 -m unittest test_repeaters.TestSearch -v` +Expected: FAIL — `AttributeError: module 'repeaters' has no attribute 'search'` + +- [ ] **Step 3: Add load + search to repeaters.py** (after `normalize_csv`) + +```python +def load(path): + """Read a normalized repeaters.json (list of records). Missing file -> [].""" + try: + with open(path) as f: + data = json.load(f) + except FileNotFoundError: + return [] + return data if isinstance(data, list) else data.get("repeaters", []) + + +def search(records, q, limit=25): + """Filter by case-insensitive substring (callsign/location), keep rank order.""" + q = (q or "").strip().lower() + out = [r for r in records + if not q or q in f"{r.get('callsign','')} {r.get('location','')}".lower()] + out.sort(key=lambda r: r.get("rank", 1_000_000)) + return out[:limit] +``` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `python3 -m unittest test_repeaters -v` +Expected: PASS (8 normalize + 4 search + 1 load = 13 tests) + +- [ ] **Step 5: Commit** + +```bash +git add repeaters.py test_repeaters.py +git commit -m "feat: repeater load + rank-ordered search" +``` + +--- + +## Task 5: CSV ingest CLI + generate repeaters.json + +**Files:** +- Modify: `repeaters.py` (add `ingest_csv` + `__main__`) +- Create: `repeaters.json` (generated output) + +- [ ] **Step 1: Add ingest_csv + __main__ to repeaters.py** (end of file) + +```python +def ingest_csv(csv_path, out_path): + """Read a RepeaterBook CSV, filter to FM/DSTAR on 2m/70cm, write repeaters.json. + Returns the number of records written. File order is preserved as `rank`.""" + recs = [] + with open(csv_path, newline="") as f: + for i, row in enumerate(csv.DictReader(f)): + rec = normalize_csv(row, i) + f_mhz = rec["output_mhz"] + if f_mhz is None: + continue + modes = (row.get("Modes") or "").upper() + if "FM" not in modes and "DSTAR" not in modes: + continue + if not (144 <= f_mhz < 148 or 420 <= f_mhz < 450): + continue + recs.append(rec) + with open(out_path, "w") as f: + json.dump(recs, f, indent=1) + return len(recs) + + +if __name__ == "__main__": + if len(sys.argv) >= 3 and sys.argv[1] == "ingest": + out = sys.argv[3] if len(sys.argv) > 3 else "repeaters.json" + n = ingest_csv(sys.argv[2], out) + print(f"wrote {n} repeaters -> {out}") + else: + print("usage: python3 repeaters.py ingest [out.json]", file=sys.stderr) + sys.exit(2) +``` + +- [ ] **Step 2: Generate repeaters.json from the real CSV** + +Run: `python3 repeaters.py ingest repeaterbook/RB_2606141409.csv repeaters.json` +Expected: `wrote 1072 repeaters -> repeaters.json` (±a few) + +- [ ] **Step 3: Sanity-check the output** + +Run: `python3 -c "import repeaters as R; d=R.load('repeaters.json'); print('count', len(d)); print('first', d[0]['callsign'], d[0]['output_mhz'], d[0]['duplex'], d[0]['tone_hz'], d[0]['mode']); print('top5 search FM', [r['callsign'] for r in R.search(d,'',5)])"` +Expected: count ~1072; first record is the Annandale machine (rank 0); a 5-item list. + +- [ ] **Step 4: Commit** + +```bash +git add repeaters.py repeaters.json +git commit -m "feat: CSV ingest CLI + generated repeaters.json" +``` + +--- + +## Task 6: Radio control methods + live verification + +**Files:** +- Modify: `radio.py` (after `squelch_open`, ~line 158) + +> No unit tests (live serial I/O). The provisional offset/tone encodings get ground-truthed here. **Requires the radio on `/dev/ttyUSB0`; stop the server first.** + +- [ ] **Step 1: Back up radio.py** + +Run: `cp radio.py .backup/radio.py-$(date +%s)` + +- [ ] **Step 2: Add methods to the `Radio` class** + +```python + # ---- repeater config (candidate commands; verify live) ---------------- + def set_duplex(self, direction): + """direction: '+', '-', or 'simplex'.""" + code = {"+": civ.DUP_PLUS, "-": civ.DUP_MINUS, + "simplex": civ.DUP_SIMPLEX}.get(direction) + if code is None: + raise ValueError(f"bad duplex {direction!r}") + return self._command(civ.CMD_DUPLEX, bytes([code])) + + def set_offset(self, hz): + return self._command(civ.CMD_OFFSET, civ.offset_to_bcd(hz)) + + def get_offset(self): + return civ.bcd_to_offset(self.transact(civ.CMD_OFFSET).data) + + def set_tone(self, hz): + return self._command(civ.CMD_TONE_PARAM, + bytes([civ.SUB_RPT_TONE]) + civ.tone_to_bcd(hz)) + + def get_tone(self): + return civ.bcd_to_tone(self.transact(civ.CMD_TONE_PARAM, + bytes([civ.SUB_RPT_TONE])).data[1:]) + + def set_tone_on(self, on): + return self._command(civ.CMD_TONE_SWITCH, + bytes([civ.SUB_TONE_ENC, 0x01 if on else 0x00])) + + def tune_repeater(self, rec): + """Apply a normalized record: freq -> duplex/offset -> tone. + Returns (steps, errors): each step True/False; errors keyed by step.""" + steps, errors = {}, {} + + def attempt(name, fn): + try: + fn(); steps[name] = True + except (CIVError, ValueError, OSError) as e: + steps[name] = False; errors[name] = str(e) + + attempt("freq", lambda: self.set_frequency(int(round(rec["output_mhz"] * 1e6)))) + duplex = rec.get("duplex", "simplex") + attempt("duplex", lambda: self.set_duplex(duplex)) + if duplex != "simplex": + attempt("offset", lambda: self.set_offset(int(round(rec.get("offset_mhz", 0) * 1e6)))) + if rec.get("tone_mode") == "ctcss" and rec.get("tone_hz"): + attempt("tone_freq", lambda: self.set_tone(rec["tone_hz"])) + attempt("tone_on", lambda: self.set_tone_on(True)) + return steps, errors +``` + +- [ ] **Step 3: Syntax check** + +Run: `python3 -c "import radio; print('ok', hasattr(radio.Radio, 'tune_repeater'))"` +Expected: `ok True` + +- [ ] **Step 4: Capture current radio state for each new command** (radio attached, server stopped) + +Run: +```bash +pkill -f "server.py --port 8550" 2>/dev/null +python3 -c " +from radio import Radio +import civ +with Radio('/dev/ttyUSB0', 9600) as r: + for cmd, sub, label in [(civ.CMD_OFFSET, b'', 'offset'), + (civ.CMD_TONE_PARAM, bytes([civ.SUB_RPT_TONE]), 'tone')]: + try: + print(label, 'raw:', r.transact(cmd, sub).data.hex(' ')) + except Exception as e: + print(label, 'ERR', e) +" +``` +Expected: hex bytes for offset and tone (or an error → wrong command number). + +- [ ] **Step 5: Reconcile encoding with observed bytes** + +- Command **errors/NAKs** → wrong command number; consult the ID-5100 manual CI-V table, fix the constant in `civ.py`, repeat Step 4. +- Returns bytes → decode with the current encoder; compare to the radio's displayed offset/tone. If mismatch, adjust `offset_to_bcd`/`bcd_to_offset` (byte count/order/units) or `tone_to_bcd`, and **add a real-capture test** to `test_civ.py` pinning the observed bytes (like `REAL_BCD`). + +- [ ] **Step 6: No-op write-back (proves write path ACKs without changing state)** + +Run: +```bash +python3 -c " +from radio import Radio +with Radio('/dev/ttyUSB0', 9600) as r: + print('offset', r.get_offset()); r.set_offset(r.get_offset()); print('offset OK') + print('tone', r.get_tone()); r.set_tone(r.get_tone()); print('tone OK') +" +``` +Expected: prints values then `OK` per trusted command. Any exception = that command stays untrusted; note it (the UI will show that step failing — intended). + +- [ ] **Step 7: Commit** (record verification result in DECISIONS.md) + +```bash +git add radio.py civ.py test_civ.py DECISIONS.md +git commit -m "feat: radio duplex/offset/tone control + live-verified encodings" +``` + +--- + +## Task 7: GET /api/repeaters in server.py + +**Files:** +- Modify: `server.py` + +- [ ] **Step 1: Back up server.py** + +Run: `cp server.py .backup/server.py-$(date +%s)` + +- [ ] **Step 2: Add import + path constant** (after existing imports, near line 21) + +```python +import repeaters + +REPEATERS_JSON = os.path.join(HERE, "repeaters.json") +``` + +- [ ] **Step 3: Add the route to `do_GET`** (in the `elif` chain, before the final `else`) + +```python + elif self.path.startswith("/api/repeaters"): + from urllib.parse import urlparse, parse_qs + qs = parse_qs(urlparse(self.path).query) + q = qs.get("q", [""])[0] + limit = int(qs.get("limit", ["25"])[0]) + recs = repeaters.search(repeaters.load(REPEATERS_JSON), q, limit) + self._json({"ok": True, "repeaters": recs}) +``` + +- [ ] **Step 4: Verify** (radio attached; use port 8551 to avoid the live panel) + +Run: +```bash +pkill -f "server.py --port 8550" 2>/dev/null +python3 server.py --port 8551 & +sleep 1 +curl -s 'http://127.0.0.1:8551/api/repeaters?limit=3' | python3 -m json.tool +curl -s 'http://127.0.0.1:8551/api/repeaters?q=fairfax&limit=3' | python3 -m json.tool +pkill -f "server.py --port 8551" +``` +Expected: `{"ok": true, "repeaters": [...3 rank-ordered records...]}`, and the filtered query returns Fairfax matches. + +- [ ] **Step 5: Commit** + +```bash +git add server.py +git commit -m "feat: GET /api/repeaters endpoint" +``` + +--- + +## Task 8: POST /api/tune-repeater in server.py + +**Files:** +- Modify: `server.py` + +- [ ] **Step 1: Back up server.py** + +Run: `cp server.py .backup/server.py-$(date +%s)` + +- [ ] **Step 2: Extend `apply_control`** — change its tail so the new path returns a per-step result: + +```python + elif path == "/api/tune-repeater": + steps, errors = radio.tune_repeater(body) + return {"ok": bool(steps.get("freq")), "steps": steps, "errors": errors} + else: + raise CIVError("unknown control") + return {"ok": True} +``` + +- [ ] **Step 3: Verify** (radio attached) + +Run: +```bash +pkill -f "server.py --port 8550" 2>/dev/null +python3 server.py --port 8551 & +sleep 1 +curl -s -X POST http://127.0.0.1:8551/api/tune-repeater \ + -H 'Content-Type: application/json' \ + -d '{"output_mhz":147.30,"duplex":"+","offset_mhz":0.6,"tone_mode":"ctcss","tone_hz":167.9}' \ + | python3 -m json.tool +pkill -f "server.py --port 8551" +``` +Expected: `{"ok": true, "steps": {"freq": true, "duplex": ..., "offset": ..., "tone_freq": ..., "tone_on": ...}, "errors": {...}}`. Some steps may be `false` if Task 6 left commands untrusted — intended, visible behavior. + +- [ ] **Step 4: Commit** + +```bash +git add server.py +git commit -m "feat: POST /api/tune-repeater (per-step result)" +``` + +--- + +## Task 9: Repeaters card in panel.html + +**Files:** +- Modify: `panel.html` + +- [ ] **Step 1: Back up panel.html** + +Run: `cp panel.html .backup/panel.html-$(date +%s)` + +- [ ] **Step 2: Add the card markup** — insert after the Levels card's closing `` (after line 200, before the `` that closes `.panel`): + +```html +
+
Repeaters · nearest first
+
+ +
+
+
+``` + +- [ ] **Step 3: Add CSS** — inside ``: + +```css +.rblist{display:flex;flex-direction:column;gap:6px;margin-top:10px;max-height:300px;overflow-y:auto} +.rbrow{display:flex;flex-direction:column;gap:3px; + background:#0c0b08;border:1px solid #3a352b;border-radius:8px;padding:9px 11px;cursor:pointer} +.rbrow:active{transform:translateY(1px)} +.rbrow .cs{font-family:'Saira Condensed',sans-serif;font-weight:800;color:var(--ink);letter-spacing:.06em} +.rbrow .dv{color:var(--accent-hi);border:1px solid var(--accent);border-radius:10px; + padding:1px 6px;font-size:9px;letter-spacing:.1em;margin-left:6px} +.rbrow .meta{color:var(--ink-dim);font-size:11px} +.rbrow .steps{font-family:'Chivo Mono';font-size:10px;letter-spacing:.04em;color:var(--ink-dim);min-height:12px} +.rbrow .steps .ok{color:var(--led-on)} .rbrow .steps .no{color:var(--red)} +``` + +- [ ] **Step 4: Add JS** — inside ` + + diff --git a/radio.py b/radio.py new file mode 100644 index 0000000..986d881 --- /dev/null +++ b/radio.py @@ -0,0 +1,158 @@ +""" +Serial transport + high-level control for the ICOM ID-5100 over CI-V. + +Talks to the RT Systems USB-29A cable (FTDI) plugged into the radio's [SP2] +jack. Uses pure-stdlib termios — no pyserial. Pairs with civ.py (the codec). + +Example: + from radio import Radio + with Radio("/dev/ttyUSB0", 9600) as r: + print(r.get_frequency()) # Hz + r.set_frequency(146_520_000) +""" +import os +import time +import termios + +import civ + +BAUD_CONST = { + 1200: termios.B1200, 4800: termios.B4800, 9600: termios.B9600, + 19200: termios.B19200, 38400: termios.B38400, 115200: termios.B115200, +} + +# Mode byte -> name. Analog codes are standard ICOM; confirm DV against the +# manual's CI-V table (overridden empirically where the live radio disagrees). +MODE_NAMES = {0x00: "LSB", 0x01: "USB", 0x02: "AM", 0x03: "CW", + 0x05: "FM", 0x17: "DV"} +MODE_CODES = {v: k for k, v in MODE_NAMES.items()} + +ACK_OK = 0xFB +ACK_NG = 0xFA + + +class CIVError(Exception): + pass + + +class Radio: + def __init__(self, port="/dev/ttyUSB0", baud=9600, timeout=0.6): + self.port = port + self.baud = baud + self.timeout = timeout + self.fd = None + + # ---- lifecycle ------------------------------------------------------- + def open(self): + speed = BAUD_CONST.get(self.baud) + if speed is None: + raise ValueError(f"unsupported baud {self.baud}") + fd = os.open(self.port, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK) + iflag, oflag, cflag, lflag, ispeed, ospeed, cc = termios.tcgetattr(fd) + cflag = termios.CS8 | termios.CREAD | termios.CLOCAL + cc = list(cc) + cc[termios.VMIN] = 0 + cc[termios.VTIME] = 0 + termios.tcsetattr(fd, termios.TCSANOW, [0, 0, cflag, 0, speed, speed, cc]) + termios.tcflush(fd, termios.TCIOFLUSH) + self.fd = fd + return self + + def close(self): + if self.fd is not None: + os.close(self.fd) + self.fd = None + + def __enter__(self): + return self.open() + + def __exit__(self, *exc): + self.close() + + # ---- raw exchange ---------------------------------------------------- + def _read_for(self, seconds): + buf = bytearray() + deadline = time.monotonic() + seconds + while time.monotonic() < deadline: + try: + chunk = os.read(self.fd, 256) + except BlockingIOError: + chunk = b"" + if chunk: + buf.extend(chunk) + else: + time.sleep(0.005) + return bytes(buf) + + def transact(self, cmd, data=b""): + """Send a command, return the radio's reply frame. Returns as soon as a + frame from the radio (not our own bus echo) is parsed, so it doesn't + burn the full timeout on every call.""" + if self.fd is None: + raise CIVError("port not open") + termios.tcflush(self.fd, termios.TCIFLUSH) + os.write(self.fd, civ.build_frame(cmd, data)) + buf = bytearray() + deadline = time.monotonic() + self.timeout + while time.monotonic() < deadline: + try: + chunk = os.read(self.fd, 256) + except BlockingIOError: + chunk = b"" + if chunk: + buf.extend(chunk) + for fr in civ.parse_frames(bytes(buf)): + if fr.frm == civ.RADIO_ADDR: # radio's reply, not our echo + return fr + else: + time.sleep(0.005) + raise CIVError(f"no reply to cmd 0x{cmd:02X} (got {bytes(buf).hex(' ') or 'nothing'})") + + def _command(self, cmd, data): + """Send a set-command and require an OK ack.""" + fr = self.transact(cmd, data) + if fr.cn == ACK_NG: + raise CIVError(f"radio rejected cmd 0x{cmd:02X}") + if fr.cn not in (ACK_OK, cmd): + raise CIVError(f"unexpected ack 0x{fr.cn:02X} for cmd 0x{cmd:02X}") + return True + + # ---- frequency ------------------------------------------------------- + def get_frequency(self): + return civ.bcd_to_freq(self.transact(civ.CMD_READ_FREQ).data) + + def set_frequency(self, hz): + return self._command(civ.CMD_SET_FREQ, civ.freq_to_bcd(hz)) + + # ---- mode ------------------------------------------------------------ + def get_mode(self): + data = self.transact(civ.CMD_READ_MODE).data + code = data[0] if data else None + return MODE_NAMES.get(code, f"0x{code:02X}" if code is not None else "?"), code + + def set_mode(self, name): + code = MODE_CODES.get(name.upper()) + if code is None: + raise ValueError(f"unknown mode {name}; known: {sorted(MODE_CODES)}") + return self._command(civ.CMD_SET_MODE, bytes([code])) + + # ---- levels ---------------------------------------------------------- + def get_volume(self): + return civ.bcd_to_level(self.transact(civ.CMD_LEVEL, bytes([civ.SUB_AF])).data[1:]) + + def set_volume(self, value): + return self._command(civ.CMD_LEVEL, bytes([civ.SUB_AF]) + civ.level_to_bcd(value)) + + def get_squelch_level(self): + return civ.bcd_to_level(self.transact(civ.CMD_LEVEL, bytes([civ.SUB_SQL_LEVEL])).data[1:]) + + def set_squelch_level(self, value): + return self._command(civ.CMD_LEVEL, bytes([civ.SUB_SQL_LEVEL]) + civ.level_to_bcd(value)) + + # ---- meters ---------------------------------------------------------- + def get_smeter(self): + return civ.bcd_to_level(self.transact(civ.CMD_METER, bytes([civ.SUB_SMETER])).data[1:]) + + def squelch_open(self): + data = self.transact(civ.CMD_METER, bytes([civ.SUB_SQL_STATUS])).data + return bool(data[1]) if len(data) > 1 else False diff --git a/repeaterbook/RB_2606141409.csv b/repeaterbook/RB_2606141409.csv new file mode 100644 index 0000000..d6f4a0e --- /dev/null +++ b/repeaterbook/RB_2606141409.csv @@ -0,0 +1,1259 @@ +Output Freq,Input Freq,Offset,Uplink Tone,Downlink Tone,Call,"Location",County,State,Modes,Digital Access +147.210000,147.81000,+,110.9,,W4CIA,"Annandale - Inova Fairfax Hospital",Fairfax,Virginia,FM Fusion , +145.176250,144.57625,-,,,N3QEM,"Vienna",Fairfax,Virginia,DMR ,13 +146.790000,146.19000,-,77.0,77.0,NV4FM,"Fairfax",Fairfax,Virginia,FM , +145.340000,144.74000,-,,,NV4FM,"Tysons Corner",Fairfax,Virginia,DSTAR , +448.035000,443.03500,-,,,NV4FM,"Tysons Corner",Fairfax,Virginia,DSTAR , +441.337500,446.33750,+,,,N9KET,"Tysons Corner",Fairfax,Virginia,DMR ,1 +146.910000,146.31000,-,77.0,77.0,NV4FM,"Tysons Corner",Fairfax,Virginia,FM , +447.025000,442.02500,-,77.0,77.0,NV4FM,"Tysons Corner",Fairfax,Virginia,FM , +443.062500,448.06250,+,,,N3QEM,"Tysons Corner",Fairfax,Virginia,DMR ,1 +441.650000,446.65000,+,,,N9KET,"Tysons Corner",Fairfax,Virginia,DMR ,2 +448.375000,443.37500,-,CSQ,67.0,K4XY,"Fairfax - Fair Oaks Hospital",Fairfax,Virginia,FM , +146.625000,146.02500,-,107.2,107.2,W4AVA,"Falls Church",Fairfax,Virginia,FM , +447.625000,442.62500,-,107.2,107.2,W4AVA,"Falls Church",(independent),Virginia,FM , +146.685000,146.08500,-,110.9,,K4HTA,"Tysons Corner",Fairfax,Virginia,FM EchoLink , +147.375000,147.97500,+,131.8,131.8,W8RBJ,"Reston - The Atrium",Fairfax,Virginia,FM EchoLink , +442.060000,447.06000,+,,,W4HFH,"Alexandria - Hospital",(independent),Virginia,DSTAR , +145.380000,144.78000,-,,,W4HFH,"Alexandria",(independent),Virginia,DSTAR , +145.150000,144.55000,-,107.2,107.2,WB4MJF,"Arlington",Arlington,Virginia,FM , +145.470000,144.87000,-,107.2,,W4WVP,"Arlington",Arlington,Virginia,FM , +444.550000,449.55000,+,88.5,,K4AF,"Arlington",Arlington,Virginia,FM , +448.625000,443.62500,-,107.2,,W4AVA,"Arlington",Arlington,Virginia,FM , +449.325000,444.32500,-,151.4,,W4WVP,"Arlington",Arlington,Virginia,FM , +441.450000,446.45000,+,110.9,,W4CIA,"Arlington",Arlington,Virginia,FM Fusion , +147.315000,147.91500,+,107.2,,W4HFH,"Alexandria",(independent),Virginia,FM , +444.600000,449.60000,+,107.2,,W4HFH,"Alexandria",(independent),Virginia,FM , +443.100000,448.10000,+,,,N3JLT,"Alexandria",(independent),Virginia,DMR ,1 +145.163750,144.56375,-,,,N3QEM,"Herndon",Fairfax,Virginia,DMR ,13 +443.000000,448.00000,+,88.5,,N1RM,"Reston",Fairfax,Virginia,FM , +442.437500,447.43750,+,,,N3QEM,"Herndon - Worldgate",Fairfax,Virginia,DMR ,1 +147.240000,147.84000,+,107.2,107.2,W4IY,"Woodbridge",Prince William,Virginia,FM AllStar EchoLink , +444.900000,449.90000,+,127.3,127.3,W4IY,"Woodbridge",Prince William,Virginia,FM Fusion WIRES-X , +146.655000,146.05500,-,141.3,141.3,K4US,"Alexandria - GW National Masonic Memorial",(independent),Virginia,FM Fusion , +449.975000,444.97500,-,107.2,107.2,WA3KOK,"Washington - WAMU-FM Tower",,District of Columbia,FM IRLP P-25 ,293 +147.330000,147.93000,+,203.5,,K4IAD,"Dulles - Dulles Airport",Loudoun,Virginia,FM , +145.310000,144.71000,-,77.0,77.0,KI4AD,"Ashburn - Dulles Airport",Loudoun,Virginia,FM Fusion , +444.750000,449.75000,+,100.0,,K4IAD,"Chantilly - Dulles Airport",Loudoun,Virginia,FM , +443.500000,448.50000,+,110.9,110.9,K4GVT,"Manassas",(independent),Virginia,FM , +449.375000,444.37500,-,203.5,,N4FRS,"Alexandria",(independent),Virginia,FM DSTAR , +442.412500,447.41250,+,,,W4HFH,"Alexandria",(independent),Virginia,DMR ,1 +444.850000,449.85000,+,,,KA4DCS,"Woodbridge - Potomac Mills",Prince William,Virginia,FM , +145.190000,144.59000,-,151.4,,W3DOS,"Washington - Harry S Truman Bldg",,District of Columbia,FM , +442.512500,447.51250,+,,,W4OVH,"Manassas - NOVEC Comm Tower",Prince William,Virginia,DSTAR , +146.865000,146.26500,-,,,W4OVH,"Manassas - NOVEC Comm Tower",Prince William,Virginia,DSTAR , +147.360000,147.96000,+,,,W3HAC,"Washington",,District of Columbia,DMR ,1 +448.875000,443.87500,-,,,KC3VO,"Washington",,District of Columbia,FM , +145.430000,144.83000,-,114.8,114.8,K3MRC,"Washington",,District of Columbia,FM Fusion , +145.290000,144.69000,-,156.7,,K3YGG,"Bethesda - NIH",Montgomery,Maryland,FM EchoLink , +447.175000,442.17500,-,156.7,,N3ADV,"Washington",,District of Columbia,FM , +145.110000,144.51000,-,,,KA3LAO,"Washington",,District of Columbia,DMR ,1 +147.270000,147.87000,+,100.0,,W3DCA,"Washington",,District of Columbia,FM , +146.970000,146.37000,-,100.0,,W4OVH,"Manassas - Water Tank",Prince William,Virginia,FM , +442.200000,447.20000,+,100.0,,W4OVH,"Manassas - Water Tank",Prince William,Virginia,FM Fusion , +147.045000,147.64500,+,77.0,77.0,K3VOA,"Washington - Wilbur J Cohen Bldg",,District of Columbia,FM , +448.575000,443.57500,-,77.0,77.0,K3VOA,"Washington - Wilbur J Cohen Bldg",,District of Columbia,FM , +442.700000,447.70000,+,103.5,,W3NAB,"Washington",,District of Columbia,FM AllStar , +444.162500,449.16250,+,,,W3HAC,"Washington",,District of Columbia,DMR , +146.715000,146.11500,-,110.9,,KC3BFB,"Fort Washington",Prince George's,Maryland,FM , +147.180000,147.78000,+,156.7,,KA3LAO,"Silver Spring",Montgomery,Maryland,FM P-25 ,293 +147.225000,147.82500,+,156.7,,WB3GXW,"Silver Spring",Montgomery,Maryland,FM EchoLink , +449.025000,444.02500,-,156.7,,N3AUY,"Silver Spring",Montgomery,Maryland,FM , +146.955000,146.35500,-,CSQ,,KV3B,"Rockville",Montgomery,Maryland,FM , +447.900000,442.90000,-,100.0,100.0,KQ4CI,"Ashburn",Loudoun,Virginia,FM WIRES-X , +448.825000,443.82500,-,77.0,,KI4AD,"Ashburn",Loudoun,Virginia,FM , +442.750000,447.75000,+,156.7,156.7,KV3B,"Rockville",Montgomery,Maryland,FM Fusion , +442.487500,447.48750,+,,,N3JFW,"Rockville",Montgomery,Maryland,DMR ,1 +443.900000,448.90000,+,156.7,,WA3YOO,"Rockville",Montgomery,Maryland,FM DMR P-25 ,1293 +447.675000,442.67500,-,,,KO4NCX,"Ashburn",Loudoun,Virginia,DMR DSTAR ,1 +442.137500,447.13750,+,,,WB6EFW,"Ashburn",Loudoun,Virginia,DMR ,1 +145.185000,144.58500,-,103.5,103.5,WB6EFW,"Leesburg",Loudoun,Virginia,FM AllStar EchoLink , +145.130000,144.53000,-,107.2,107.2,KA4DCS,"Haymarket",Prince William,Virginia,FM , +145.450000,144.85000,-,,,W4BRM,"Haymarket",Prince William,Virginia,DSTAR , +442.412500,447.41250,+,,,N4USI,"Haymarket",Prince William,Virginia,DSTAR , +449.025000,444.02500,-,156.7,,N3AUY,"Haymarket",Prince William,Virginia,FM , +146.610000,146.01000,-,CSQ,77.0,K3GMR,"Bladensburg",Prince George's,Maryland,FM EchoLink , +443.662500,448.66250,+,,,N3TUK,"Adelphi",Prince George's,Maryland,AllStar DMR ,1 +145.370000,144.77000,-,,,W3ARL,"Adelphi",Prince George's,Maryland,FM , +145.490000,144.89000,-,,,W3EAX,"College Park - UMD",Prince George's,Maryland,FM EchoLink , +145.230000,144.63000,-,110.9,110.9,K3ERA,"District Heights",Prince George's,Maryland,FM EchoLink Fusion , +448.225000,443.22500,-,77.0,77.0,W4BRM,"Haymarket - Bull Run Mtn",Prince William,Virginia,FM AllStar EchoLink Fusion WIRES-X , +441.887500,446.88750,+,,,KA3LAO,"Gaithersburg - The RF Connection",Montgomery,Maryland,DMR ,1 +448.325000,443.32500,-,,,W4BRM,"Haymarket - Bull Run Mtn",Prince William,Virginia,DMR ,6 +447.775000,442.77500,-,107.2,,WA3KOK,"Antioch - Bull Run Mtn",Prince William,Virginia,FM P-25 ,293 +147.270000,147.87000,+,156.7,,WA3KOK,"Germantown",Montgomery,Maryland,FM P-25 ,293 +444.200000,449.20000,+,,,KV3B,"Germantown",Montgomery,Maryland,DSTAR , +147.345000,147.94500,+,167.9,,K3FBI,"Quantico",Prince William,Virginia,FM P-25 , +444.250000,449.25000,+,156.7,,WB3GXW,"Silver Spring",Montgomery,Maryland,FM , +147.150000,147.75000,+,114.8,114.8,W3SMR,"Brandywine",Prince George's,Maryland,FM , +443.787500,448.78750,+,,,W4ATN,"Largo",Prince George's,Maryland,DMR ,3 +447.325000,442.32500,-,110.9,,K3ERA,"Lanham - Doctors Community Hospital",Prince George's,Maryland,FM , +146.835000,146.23500,-,114.8,,WA3NAN,"Greenbelt",Prince George's,Maryland,FM , +146.880000,146.28000,-,77.0,77.0,W3GMR,"Greenbelt",Prince George's,Maryland,FM , +442.100000,447.10000,+,77.0,,WA4TXE,"Leesburg",Loudoun,Virginia,FM , +146.700000,146.10000,-,77.0,,WA4TXE,"Leesburg",Loudoun,Virginia,FM , +443.600000,448.60000,+,103.5,103.5,WA3YUV,"Brandywine",Prince George's,Maryland,FM Fusion , +444.050000,449.05000,+,,,WA3KOK,"Ashton",Montgomery,Maryland,FM P-25 ,293 +442.237500,447.23750,+,,,WA3KOK,"Ashton",Montgomery,Maryland,FM DMR ,1 +444.650000,449.65000,+,,,N3LHD,"Upper Marlboro",Prince George's,Maryland,DMR ,6 +443.150000,448.15000,+,156.7,156.7,KC3BXH,"Ashton",Montgomery,Maryland,FM P-25 ,293 +147.000000,146.40000,-,156.7,,KC3BXH,"Ashton",Montgomery,Maryland,FM EchoLink P-25 ,293 +147.375000,147.97500,+,79.7,79.7,WS4VA,"Stafford",Stafford,Virginia,FM , +145.320000,144.72000,-,,,WS4VA,"Stafford",Stafford,Virginia,DSTAR , +447.275000,442.27500,-,,,WS4VA,"Stafford",Stafford,Virginia,DSTAR , +441.700000,446.70000,+,,,K4AUI,"Hamilton",Loudoun,Virginia,FM , +442.150000,447.15000,+,,,W3XJ,"Bowie",Prince George's,Maryland,FM , +443.800000,448.80000,+,,,W4ATN,"Laurel",Prince George's,Maryland,DMR ,3 +145.390000,144.79000,-,,,W4ATN,"Laurel",Prince George's,Maryland,FM , +442.500000,447.50000,+,156.7,,W3LRC,"Laurel",Prince George's,Maryland,FM , +147.165000,147.76500,+,167.9,167.9,W4VA,"Warrenton",Fauquier,Virginia,FM AllStar EchoLink , +442.250000,447.25000,+,167.9,167.9,W4VA,"Warrenton",Fauquier,Virginia,FM , +446.412500,441.41250,-,,,KQ4TNV,"Stafford",Stafford,Virginia,DMR DSTAR Fusion ,1 +442.487500,447.48750,+,,,WU5MC,"Stafford",Stafford,Virginia,DSTAR , +145.270000,144.67000,-,79.7,79.7,WS4VA,"Stafford",Stafford,Virginia,FM , +442.450000,447.45000,+,79.7,,WS4VA,"Stafford",Stafford,Virginia,FM Fusion , +147.105000,147.70500,+,107.2,CSQ,W3VPR,"Davidsonville",Anne Arundel,Maryland,FM , +444.400000,449.40000,+,107.2,107.2,W3VPR,"Davidsonville",Anne Arundel,Maryland,FM , +442.712500,447.71250,+,,,KA3LAO,"Jessup",Anne Arundel,Maryland,DMR ,1 +146.760000,146.16000,-,107.2,107.2,WA3DZD,"Jessup",Anne Arundel,Maryland,FM , +444.000000,449.00000,+,107.2,107.2,WA3DZD,"Jessup",Anne Arundel,Maryland,FM , +442.462500,447.46250,+,,,N3LHD,"Aquasco",Prince George's,Maryland,DMR ,1 +442.550000,447.55000,+,107.2,,N3SCP,"Gambrills",Anne Arundel,Maryland,FM Fusion WIRES-X , +449.925000,444.92500,-,,,N3JLT,"Bluemont - Mt Weather",Loudoun,Virginia,DMR ,1 +147.300000,147.90000,+,146.2,,N3JLT,"Bluemont - Blue Ridge",Loudoun,Virginia,FM , +448.275000,443.27500,-,156.7,156.7,K3CUJ,"Cooksville",Howard,Maryland,FM Fusion , +147.390000,147.99000,+,156.7,CSQ,K3CUJ,"Cooksville",Howard,Maryland,FM Fusion , +147.135000,147.73500,+,156.7,156.7,K3CUJ,"Columbia",Howard,Maryland,FM Fusion , +145.250000,144.65000,-,88.5,,N3PZZ,"Dahlgren - Potomac River Bridge",King George,Virginia,FM , +145.330000,144.73000,-,88.5,,N3PZZ,"King George - Dahlgren Naval Support Fac",King George,Virginia,FM , +442.400000,447.40000,+,,,KP4IP,"Millersville",Anne Arundel,Maryland,DMR ,1 +448.575000,443.57500,-,69.3,,W3CGT,"Mount Airy",Carroll,Maryland,FM , +147.075000,147.67500,+,107.2,107.2,W3VPR,"Crownsville",Anne Arundel,Maryland,FM EchoLink , +442.400000,447.40000,+,,,WX4EMC,"Fredericksburg",(independent),Virginia,DMR ,1 +442.850000,447.85000,+,79.7,79.7,AE4ML,"Fredericksburg",(independent),Virginia,FM P-25 ,293 +146.775000,146.17500,-,110.9,110.9,KC8VFN,"King George - Locust Point",King George,Virginia,FM , +146.985000,146.38500,-,156.7,156.7,K3CAL,"Sunderland",Calvert,Maryland,FM EchoLink Fusion , +441.637500,446.63750,+,,,N3PPH,"Sunderland - Mt Hope Comm Ctr",Calvert,Maryland,DMR ,1 +443.300000,448.30000,+,100.0,,K3LMS,"Jefferson",Frederick,Maryland,FM , +448.475000,443.47500,-,79.7,CSQ,K4GVA,"King George",King George,Virginia,FM , +146.745000,146.14500,-,107.2,107.2,W4KGC,"King George",King George,Virginia,FM , +449.525000,444.52500,-,100.0,,N3EZD,"Ellicott City",Howard,Maryland,FM , +441.837500,446.83750,+,,,KB3CMA,"Annapolis - Broad Creek Park",Anne Arundel,Maryland,DMR ,1 +442.300000,447.30000,+,107.2,107.2,KB3CMA,"Annapolis - Broad Creek Park",Anne Arundel,Maryland,FM Fusion , +146.805000,146.20500,-,107.2,CSQ,W3CU,"Millersville",Anne Arundel,Maryland,FM EchoLink , +449.125000,444.12500,-,107.2,,W3CU,"Millersville",Anne Arundel,Maryland,FM Fusion , +147.195000,147.79500,+,156.7,156.7,N3PX,"Mechanicsville",St Mary's,Maryland,FM , +145.250000,144.65000,-,146.2,,K3HP,"Frederick",Frederick,Maryland,FM , +147.060000,147.66000,+,146.2,146.2,K3MAD,"Frederick",Frederick,Maryland,FM , +443.400000,448.40000,+,136.5,136.5,WA3KOK,"Frederick",Frederick,Maryland,FM P-25 ,293 +443.162500,448.16250,+,,,N8RAT,"Blue Mountain - WAIW Tower",Warren,Virginia,DMR ,1 +442.600000,447.60000,+,127.3,,N3MIR,"Glen Burnie",Anne Arundel,Maryland,FM , +146.565000,144.60000,s,,,N3LPV,"Glen Burnie",Anne Arundel,Maryland,FM EchoLink , +147.015000,147.61500,+,79.7,79.7,K4TS,"Fredericksburg - Chancellor Landfill",Spotsylvania,Virginia,FM , +147.285000,147.88500,+,107.2,,K3PZN,"Sykesville",Carroll,Maryland,FM , +443.700000,448.70000,+,179.9,179.9,N3FI,"Barstow",Calvert,Maryland,FM Fusion , +443.850000,448.85000,+,79.7,79.7,K4TS,"Fredericksburg - Chancellor Landfill",Spotsylvania,Virginia,FM Fusion , +146.640000,146.04000,-,156.7,156.7,K3ERM,"Frederick",Frederick,Maryland,FM , +444.350000,449.35000,+,100.0,100.0,W3ARK,"Frederick - Braddock Mtn",Frederick,Maryland,FM , +145.250000,144.65000,-,110.9,,N3KUN,"Chaptico",St Mary's,Maryland,FM , +441.387500,446.38750,+,,,N3PPH,"Prince Frederick",Calvert,Maryland,DMR ,1 +442.250000,447.25000,+,107.2,107.2,WA3KOK,"Baltimore - Halethorpe",Baltimore,Maryland,FM P-25 ,293 +442.350000,447.35000,+,123.0,,N3UR,"Linden - Blue Ridge Mtns",Fauquier,Virginia,FM , +444.150000,449.15000,+,77.0,77.0,N3UHD,"Linden",Fauquier,Virginia,FM EchoLink , +444.350000,449.35000,+,,,WG3K,"Chesapeake Beach",Calvert,Maryland,DSTAR , +444.750000,449.75000,+,173.8,173.8,K4IAD,"Millwood",Clarke,Virginia,FM , +146.850000,146.25000,-,77.0,,WA4TXE,"Charles Town",Jefferson,West Virginia,FM , +442.575000,447.57500,+,79.7,79.7,AE4ML,"Fredericksburg - SRMC",Spotsylvania,Virginia,FM P-25 ,293 +145.300000,144.70000,-,,,WX4EMC,"Fredericksburg - Cosners",Spotsylvania,Virginia,DMR ,1 +443.350000,448.35000,+,156.7,156.7,WB3DZO,"Randallstown",Baltimore,Maryland,FM Fusion , +145.210000,144.61000,-,141.3,,K4QJZ,"Front Royal - High Knob Mtn",Warren,Virginia,FM , +442.725000,447.72500,+,107.2,,K4QJZ,"Front Royal - High Knob Mtn",Warren,Virginia,FM P-25 ,293 +442.900000,447.90000,+,162.2,162.2,K3AYV,"Baltimore - Pigtown",Baltimore,Maryland,FM , +441.787500,446.78750,+,,,N3PPH,"Mechanicsville",St Mary's,Maryland,DMR ,1 +444.300000,449.30000,+,141.3,141.3,KC4RCR,"Berryville",Clarke,Virginia,FM AllStar EchoLink , +442.800000,447.80000,+,79.7,79.7,N3ITA,"Frederick",Frederick,Maryland,FM P-25 ,797 +444.100000,449.10000,+,167.9,CSQ,N3ST,"Frederick - Gambrill Mtn",Frederick,Maryland,FM , +448.425000,443.42500,-,100.0,100.0,K3ERM,"Frederick - Gambrill State Park",Frederick,Maryland,FM Fusion WIRES-X , +146.730000,146.13000,-,141.3,141.3,W3FDK,"Frederick - Gambrill State Park",Frederick,Maryland,FM AllStar EchoLink , +441.962500,446.96250,+,,,K3DO,"Frederick - Gambrill State Park",Frederick,Maryland,DMR DSTAR ,1 +441.800000,446.80000,+,141.3,141.3,W3FDK,"Frederick - Gambrill State Park",Frederick,Maryland,FM Fusion WIRES-X , +444.800000,449.80000,+,,,W3FDK,"Frederick - Gambrill State Park",Frederick,Maryland,DSTAR , +447.875000,442.87500,-,,,N2XHZ,"Spotsylvania",Spotsylvania,Virginia,FM , +147.195000,147.79500,+,179.9,,N3EJT,"Owings Mills",Baltimore,Maryland,DMR ,1 +449.075000,444.07500,-,,,N3CDY,"Owings Mills",Baltimore,Maryland,DMR ,1 +448.675000,443.67500,-,91.5,,KC3APF,"Dundalk - Key Bridge",Baltimore,Maryland,FM Fusion WIRES-X , +442.950000,447.95000,+,94.8,CSQ,KD3SU,"Boonsboro",Washington,Maryland,FM , +146.850000,146.25000,-,156.7,,W3BPT,"Hollywood",St Mary's,Maryland,DMR ,1 +145.350000,144.75000,-,156.7,,N3PPH,"Hollywood - Hollywood Fire Department",St Mary's,Maryland,FM , +449.675000,444.67500,-,167.9,CSQ,N3ST,"Timonium",Baltimore,Maryland,FM , +145.410000,144.81000,-,114.8,114.8,K3PZN,"Westminster",Carroll,Maryland,FM , +449.875000,444.87500,-,127.3,127.3,K3PZN,"Westminster",Carroll,Maryland,FM Fusion , +146.670000,146.07000,-,107.2,,W3FT,"Towson",Baltimore,Maryland,FM EchoLink , +449.275000,444.27500,-,107.2,,N3CDY,"Towson",Baltimore,Maryland,FM P-25 ,293 +441.400000,446.40000,+,,,WR3IRS,"Towson",Baltimore,Maryland,DMR ,1 +145.140000,144.54000,-,114.8,,W3DHS,"Towson",Baltimore,Maryland,DSTAR , +147.030000,147.63000,+,156.7,,WB3DZO,"Towson",Baltimore,Maryland,FM , +442.112500,447.11250,+,114.8,,W3DHS,"Towson",Baltimore,Maryland,DSTAR , +145.330000,144.73000,-,114.8,,W3DHS,"Towson",Baltimore,Maryland,FM EchoLink , +442.000000,447.00000,+,146.2,146.2,W3IF,"Winchester",Frederick,Virginia,FM Fusion , +442.050000,447.05000,+,179.9,,N2XIF,"Stephens City",Frederick,Virginia,FM EchoLink , +443.300000,448.30000,+,123.0,,KC3FOQ,"Leonardtown - Fairgrounds",St Mary's,Maryland,FM Fusion , +147.390000,147.99000,+,123.0,,KC3FOQ,"Leonardtown - Fairgrounds",St Mary's,Maryland,FM Fusion , +146.895000,146.29500,-,110.9,110.9,KF4AH,"Montross",Westmoreland,Virginia,FM , +444.950000,449.95000,+,156.7,156.7,K3CAL,"Lusby - Appeal Landfill",Calvert,Maryland,FM EchoLink Fusion , +147.240000,147.84000,+,123.0,123.0,W3PGA,"Baltimore - KHS",Baltimore,Maryland,FM Fusion , +448.025000,443.02500,-,103.5,103.5,K3KMA,"Thurmont",Frederick,Maryland,FM , +449.575000,444.57500,-,123.0,123.0,W3PGA,"Baltimore - KHS",Baltimore,Maryland,FM Fusion , +145.190000,144.59000,-,110.9,,K3NXU,"Cockeysville",Baltimore,Maryland,FM , +448.525000,443.52500,-,82.5,,KB3BHO,"Cockeysville",Baltimore,Maryland,FM , +447.375000,442.37500,-,67.0,,W3DAK,"Middle River",Baltimore,Maryland,FM EchoLink , +145.150000,144.55000,-,179.9,179.9,W8ORS,"Martinsburg",Berkeley,West Virginia,FM , +147.255000,147.85500,+,123.0,,KB8UUE,"Martinsburg",Berkeley,West Virginia,FM EchoLink , +442.700000,447.70000,+,D023,,K1LLS,"Martinsburg",Berkeley,West Virginia,FM , +147.345000,147.94500,+,192.8,,N3EST,"Middle River",Baltimore,Maryland,FM , +447.125000,442.12500,-,123.0,123.0,W3ARK,"Hagerstown",Washington,Maryland,FM , +442.850000,447.85000,+,100.0,100.0,N8RAT,"Martinsburg - North Mtn",Berkeley,West Virginia,FM , +147.375000,147.97500,+,100.0,,W3CWC,"Hagerstown",Washington,Maryland,FM , +147.090000,147.69000,+,100.0,100.0,W3CWC,"Pen Mar - Quirauk Mtn",Washington,Maryland,FM Fusion , +447.975000,442.97500,-,100.0,100.0,W3CWC,"Pen Mar - High Rock",Washington,Maryland,FM Fusion WIRES-X , +145.410000,144.81000,-,100.0,,AF4CY,"Madison",Madison,Virginia,FM , +146.820000,146.22000,-,146.2,146.2,W4RKC,"Winchester - North Mtn",Frederick,Virginia,FM Fusion , +448.775000,443.77500,-,146.2,146.2,W4RKC,"Winchester - North Mtn",Frederick,Virginia,FM Fusion , +145.390000,144.79000,-,146.2,146.2,KG4Y,"Winchester - North Mtn",Frederick,Virginia,FM Fusion , +146.475000,147.47500,s,,,KA3LAO,"Fairfield",Adams,Pennsylvania,DMR ,1 +442.600000,447.60000,+,141.3,,NM4CC,"Winchester",Frederick,Virginia,FM Fusion , +146.895000,146.29500,-,CSQ,107.2,N3KZS,"Manchester",Carroll,Maryland,FM AllStar IRLP , +146.445000,147.44500,+,,,N2JEH,"Fairfield - Liberty Mtn",Adams,Pennsylvania,DMR ,1 +444.250000,449.25000,+,100.0,CSQ,KM4OGQ,"Gore",Frederick,Virginia,FM , +147.030000,147.63000,+,79.7,79.7,KX4O,"Madison - Blakey Ridge",Madison,Virginia,FM AllStar , +448.525000,443.52500,-,241.8,,KQ4PTL,"Stonyman",Page,Virginia,FM , +442.475000,447.47500,+,77.0,77.0,N3UHD,"Maurertown",Shenandoah,Virginia,FM , +441.912500,446.91250,+,,,N3YMS,"Wye Mills",Talbot,Maryland,DMR ,1 +442.200000,447.20000,+,156.7,156.7,K3EMD,"Easton - UM/Shore Reg Med Ctr",Talbot,Maryland,FM Fusion WIRES-X , +146.640000,146.04000,-,146.2,146.2,K3HKI,"Lexington Park",St Mary's,Maryland,FM , +443.800000,448.80000,+,146.2,146.2,W4CUL,"Gordonsville - Gibson Mtn",Orange,Virginia,FM EchoLink Fusion , +147.120000,147.72000,+,146.2,146.2,W4CUL,"Gordonsville - Gibson Mtn",Orange,Virginia,FM EchoLink P-25 ,293 +443.200000,448.20000,+,123.0,123.0,N8RAT,"Winchester",Hampshire,West Virginia,FM , +443.250000,448.25000,+,107.2,107.2,WA3KOK,"Banco - Fork Mtn",Madison,Virginia,FM P-25 ,293 +147.345000,147.94500,+,123.0,,K3MAD,"Clear Spring",Washington,Maryland,FM , +146.940000,146.34000,-,107.2,CSQ,KE3AO,"Centreville",Queen Anne's,Maryland,FM , +448.225000,443.22500,-,107.2,,KE3AO,"Centreville",Queen Anne's,Maryland,FM Fusion , +147.045000,147.64500,+,156.7,CSQ,K3EMD,"Easton",Talbot,Maryland,FM , +146.940000,146.34000,-,100.0,100.0,W3CWC,"Hagerstown - Fairview Mtn",Washington,Maryland,FM AllStar EchoLink Fusion , +442.650000,447.65000,+,79.7,,N3UHD,"Clear Spring",Washington,Maryland,FM EchoLink , +145.350000,144.75000,-,103.5,,W3KGN,"Gettysburg",Adams,Pennsylvania,FM , +447.675000,442.67500,-,107.2,107.2,N3ETH,"Gettysburg",Adams,Pennsylvania,FM AllStar , +145.330000,144.73000,-,131.8,131.8,W4LCE,"Louisa - McDonald St and Woolfolk Ave",Louisa,Virginia,FM Fusion , +146.670000,146.07000,-,114.8,114.8,W4GSB,"Stanley - Shenandoah NP",Page,Virginia,FM , +442.225000,447.22500,+,131.8,131.8,W4LCE,"Louisa",Louisa,Virginia,FM , +439.975000,439.975000,x,107.2,,,"Abingdon",Harford,Maryland,FM , +449.375000,444.37500,-,107.2,107.2,K2EJ,"Abingdon",Harford,Maryland,FM AllStar EchoLink IRLP Fusion , +147.060000,147.66000,+,74.4,74.4,KD4RJN,"Beaverdam - Ashland Berry Farm",Hanover,Virginia,FM Fusion WIRES-X , +444.612500,449.61250,+,,,WA4FC,"Beaverdam",Hanover,Virginia,DMR ,1 +449.612500,444.61250,-,,,KB3WHR,"Bel Air",Harford,Maryland,DMR ,1 +441.662500,446.66250,+,,,N3YMS,"Chestertown",Kent,Maryland,DMR ,1 +449.175000,444.17500,-,156.7,,K3ARS,"Chestertown - Shore Med Ctr",Kent,Maryland,FM , +446.460000,446.460000,x,,,KC3WRK,"Bel Air",Harford,Maryland,DMR , +442.737500,447.73750,+,,,K3ARS,"Worton",Kent,Maryland,DMR ,1 +147.375000,147.97500,+,156.7,156.7,K3ARS,"Worton",Kent,Maryland,FM , +146.745000,146.14500,-,123.0,,KK3L,"Berkeley Springs - Cacapon Mtn",Hampshire,West Virginia,FM , +442.450000,447.45000,+,107.2,,WA3KOK,"Berkeley Springs - Cacapon Mtn",Hampshire,West Virginia,FM P-25 ,293 +444.950000,449.95000,+,123.0,123.0,N8RAT,"Berkeley Springs - Cacapon Mtn",Hampshire,West Virginia,FM , +146.775000,146.17500,-,146.2,146.2,KC3FHC,"Bel Air",Harford,Maryland,FM , +447.987500,442.98750,-,,,KC3FHC,"Bel Air",Harford,Maryland,DSTAR , +449.775000,444.77500,-,162.2,CSQ,KC3FHC,"Forest Hill",Harford,Maryland,FM , +145.120000,144.52000,-,,,KC3FHC,"Bel Air",Harford,Maryland,DSTAR , +443.850000,448.85000,+,123.0,123.0,KK3L,"Berkeley Springs",Morgan,West Virginia,DMR ,1 +449.725000,444.72500,-,,,K3AE,"Shrewsbury",York,Pennsylvania,DMR ,1 +146.700000,146.10000,-,114.8,,K3AE,"Shrewsbury",York,Pennsylvania,FM Fusion , +147.330000,147.93000,+,123.0,,W3MUM,"Hanover - Pigeon Hills",York,Pennsylvania,FM , +445.231250,440.23125,-,,,KB3VVB,"Hanover - Pigeon Hills",York,Pennsylvania,DMR ,1 +147.120000,147.72000,+,114.8,114.8,KO3L,"Bel Air",Harford,Maryland,FM DMR DSTAR ,1 +145.470000,144.87000,-,151.4,151.4,AA4DH,"Greene - Flat Top Mtn",Greene,Virginia,FM , +146.715000,146.11500,-,146.2,,KQ4DSO,"Mount Jackson",Shenandoah,Virginia,FM EchoLink , +146.625000,146.02500,-,131.8,131.8,N4YSA,"New Market - Luray Caverns",Page,Virginia,FM WIRES-X , +443.100000,448.10000,+,103.5,,W3KGN,"Biglerville",Adams,Pennsylvania,FM , +443.350000,448.35000,+,203.5,203.5,N4YSA,"New Market - Luray Caverns",Page,Virginia,FM Fusion , +443.900000,448.90000,+,151.4,,AA4DH,"Stanardsville - Snow Mtn",Greene,Virginia,FM , +147.330000,147.93000,+,100.0,,W4NNK,"Heathsville",Northumberland,Virginia,FM , +447.725000,442.72500,-,,,N3CNJ,"Gatchellville",York,Pennsylvania,DMR P-25 Fusion ,1615 +442.700000,447.70000,+,,,WX4EMC,"Heathsville - WCNV Tower",Northumberland,Virginia,DMR ,1 +145.110000,144.51000,-,74.4,74.4,N8ELS,"Hanover",Hanover,Virginia,FM , +145.240000,144.64000,-,,,W4SVR,"Mechanicsville",Hanover,Virginia,FM Fusion , +146.715000,146.11500,-,,,W4TTL,"Walkerton",King & Queen,Virginia,FM , +145.270000,144.67000,-,74.4,,W3WAN,"Chambersburg",Franklin,Pennsylvania,FM AllStar , +443.700000,448.70000,+,131.8,131.8,N3KZ,"Chambersburg",Franklin,Pennsylvania,FM , +146.415000,147.41500,s,,,KA3LAO,"Chambersburg",Franklin,Pennsylvania,DMR ,1 +441.900000,446.90000,+,,,WR3IRS,"Chambersburg",Franklin,Pennsylvania,DMR ,1 +443.650000,448.65000,+,,,WR3IRS,"Havre de Grace",Harford,Maryland,DMR ,1 +444.750000,449.75000,+,162.2,CSQ,KC3FHC,"Havre de Grace - Harford Mem Hospital",Harford,Maryland,FM , +147.315000,147.91500,+,131.8,131.8,N8JEP,"Basye - Great North Mtn",Shenandoah,Virginia,FM Fusion , +444.150000,449.15000,+,131.8,131.8,N3KZ,"Havre de Grace",Harford,Maryland,FM , +443.437500,448.43750,+,,,K2VIZ,"Gum Spring",Goochland,Virginia,DMR ,1 +147.270000,147.87000,+,203.5,203.5,WB4IKL,"Gum Spring",Goochland,Virginia,FM Fusion , +444.650000,449.65000,+,203.5,203.5,N4GEC,"Gum Spring",Goochland,Virginia,FM , +146.865000,146.26500,-,123.0,123.0,W3ZGD,"Red Lion",York,Pennsylvania,FM Fusion , +449.425000,444.42500,-,123.0,123.0,N3NRN,"Red Lion",York,Pennsylvania,FM , +442.050000,447.05000,+,,,N3KNT,"Federalsburg",Caroline,Maryland,DMR ,1 +145.250000,144.65000,-,,,KB3UAG,"Chambersburg",Franklin,Pennsylvania,DMR ,1 +441.500000,446.50000,+,D754,D754,KB3MEC,"Galena",Kent,Maryland,FM , +444.800000,449.80000,+,203.5,203.5,KB4MIC,"Oilville",Goochland,Virginia,FM , +146.925000,146.32500,-,74.4,74.4,W3WAN,"York",York,Pennsylvania,FM AllStar , +441.150000,446.15000,+,,,WR3IRS,"York - Hallam",York,Pennsylvania,DMR ,1 +447.275000,442.27500,-,123.0,,W3HZU,"York - Rocky Ridge County Park",York,Pennsylvania,FM AllStar EchoLink , +146.925000,146.32500,-,151.4,151.4,WA4TFZ,"Charlottesville - Martha Jefferson Hospital",Albemarle,Virginia,FM , +146.850000,146.25000,-,107.2,,WA3SFJ,"Port Deposit",Cecil,Maryland,FM AllStar , +449.825000,444.82500,-,167.9,,WA3SFJ,"Port Deposit",Cecil,Maryland,FM Fusion , +444.250000,449.25000,+,151.4,151.4,WA4TFZ,"Charlottesville - Martha Jefferson Hospital",Albemarle,Virginia,FM , +145.430000,144.83000,-,67.0,,N3TWT,"Mount Holly Springs - South Mtn",Cumberland,Pennsylvania,FM EchoLink , +442.075000,447.07500,+,151.4,,KF4UCI,"Charlottesville - Carter's Mtn",Albemarle,Virginia,FM , +444.912500,449.91250,+,,,WA4FC,"Charlottesville ",(independent),Virginia,DMR ,1 +442.950000,447.95000,+,103.5,,N3RCN,"Charlestown - Water Tower",Cecil,Maryland,FM , +442.500000,447.50000,+,123.0,123.0,N8RAT,"Moorefield - Nathanial Wildlife Mgt Area",Hardy,West Virginia,FM , +145.170000,144.57000,-,151.4,151.4,K4MSR,"Palmyra",Fluvanna,Virginia,FM , +146.865000,146.26500,-,,,N3MRG,"Tyaskin - Muddy Hole",Wicomico,Maryland,DMR ,1 +145.130000,144.53000,-,131.8,131.8,K4MRA,"Harrisonburg - Massanutten Peak",Rockingham,Virginia,FM Fusion , +146.820000,146.22000,-,156.7,156.7,K3DRC,"Salisbury - WMDT Tower",Wicomico,Maryland,FM , +444.600000,449.60000,+,131.8,,K4MRA,"Harrisonburg - Massanutten Peak",Rockingham,Virginia,FM Fusion , +146.970000,146.37000,-,127.3,,W3HZU,"York - Rocky Ridge County Park",York,Pennsylvania,FM AllStar EchoLink , +443.000000,448.00000,+,151.4,151.4,W4UVA,"Charlottesville - Rice Hall (UVA Engineering)",Albemarle,Virginia,FM , +147.120000,147.72000,+,100.0,100.0,W3ACH,"Chambersburg - Clark's Knob",Franklin,Pennsylvania,FM , +444.056250,449.05625,+,,,N2JEH,"Dillsburg - Roundtop",York,Pennsylvania,DMR ,1 +146.790000,146.19000,-,,,KB3TWW,"Dillsburg",York,Pennsylvania,DMR ,1 +448.075000,443.07500,-,,,N3YMS,"Hazlettville",Kent,Delaware,DMR ,2 +444.987500,449.98750,+,,,KF4UCI,"Charlottesville - Carters Mtn",Albemarle,Virginia,DMR ,1 +444.400000,449.40000,+,103.5,,KD8IFP,"Moorefield - Branch Mtn",Hardy,West Virginia,FM , +444.637500,449.63750,+,,,KD8AZC,"Moorefield",Hardy,West Virginia,DMR ,1 +447.325000,442.32500,-,103.5,103.5,KD8AZC,"Moorefield - Branch Mtn",Hardy,West Virginia,FM , +146.730000,146.13000,-,151.4,,K4DND,"Charlottesville - Carters Mtn",Albemarle,Virginia,FM , +145.430000,144.83000,-,74.4,74.4,KG4MRA,"Richmond - WTVR Tower",(independent),Virginia,FM , +448.575000,443.57500,-,107.2,,N3RCN,"Elkton",Cecil,Maryland,FM , +448.625000,443.62500,-,114.8,114.8,N3TPL,"Holtwood - Martic Twp",Lancaster,Pennsylvania,FM Fusion , +448.775000,443.77500,-,,,KX3B,"Holtwood",Lancaster,Pennsylvania,DMR ,1 +145.110000,144.51000,-,127.3,,WA4MAS,"Richmond",(independent),Virginia,FM Fusion WIRES-X , +147.300000,147.90000,+,77.0,77.0,N3YMS,"Hazlettville",Kent,Delaware,FM , +145.450000,144.85000,-,123.0,,W3YMW,"Cumberland - Warrior Mtn WMA",Allegany,Maryland,FM , +444.662500,449.66250,+,,,K4JK,"Harrisonburg",Rockingham,Virginia,DMR ,1 +147.255000,147.85500,+,74.4,74.4,W4FJ,"Richmond - State Capitol",(independent),Virginia,FM DSTAR , +443.712500,448.71250,+,,,W4FJ,"Richmond",(independent),Virginia,DSTAR , +147.135000,147.73500,+,107.2,107.2,KC4VDZ,"Richmond - James Monroe Bldg",(independent),Virginia,FM , +442.300000,447.30000,+,114.8,114.8,KC4VDZ,"Richmond",(independent),Virginia,FM Fusion , +146.715000,146.11500,-,156.7,,N3KNT,"Seaford",Sussex,Delaware,FM EchoLink , +448.175000,443.17500,-,94.8,,N3EIO,"Quarryville",Lancaster,Pennsylvania,FM , +145.310000,144.71000,-,118.8,118.8,N3FYI,"Lancaster",Lancaster,Pennsylvania,FM AllStar EchoLink , +146.745000,146.14500,-,,,KX3B,"Holtwood",Lancaster,Pennsylvania,AllStar DMR ,6 +446.475000,441.47500,-,114.8,114.8,N3FYI,"Lancaster",Lancaster,Pennsylvania,FM AllStar EchoLink , +444.900000,449.90000,+,156.7,,W3TBG,"Seaford",Sussex,Delaware,FM , +442.812500,447.81250,+,,,N3YMS,"Seaford",Sussex,Delaware,DMR ,1 +146.835000,146.23500,-,100.0,,W4NNK,"Kilmarnock",Lancaster,Virginia,FM , +442.450000,447.45000,+,127.3,,KB3IWV,"Harrington",Kent,Delaware,FM , +145.450000,144.85000,-,,,W4GSF,"Kilmarnock - Fire Dept",Lancaster,Virginia,FM , +146.835000,146.23500,-,173.8,,W4GSF,"Kilmarnock",Lancaster,Virginia,FM , +145.625000,147.22500,+,131.8,,K4KLH,"Singer's Glen - Little North Mtn",Rockingham,Virginia,FM , +147.225000,147.82500,+,131.8,,K4KLH,"Singers Glen - Little North Mtn",Rockingham,Virginia,FM , +145.190000,144.59000,-,118.8,,N8VAA,"Moorefield",Hardy,West Virginia,FM , +146.985000,146.38500,-,123.0,,KD8IFP,"Moorefield - Branch Mtn",Hardy,West Virginia,FM , +442.050000,447.05000,+,,,K2VIZ,"Talleysville",New Kent,Virginia,DMR ,1 +145.210000,144.61000,-,156.7,,W3TBG,"Seaford - WSUX",Sussex,Delaware,FM Fusion WIRES-X , +146.910000,146.31000,-,77.0,,KC3ARC,"Woodside",Kent,Delaware,FM Fusion , +444.550000,449.55000,+,77.0,77.0,KC3ARC,"Woodside",Kent,Delaware,FM , +146.880000,146.28000,-,74.4,74.4,W4RAT,"Richmond - WCVE Tower",Chesterfield,Virginia,FM Fusion , +442.550000,447.55000,+,74.4,74.4,W4RAT,"Richmond - WCVE Tower",Chesterfield,Virginia,FM Fusion WIRES-X , +443.587500,448.58750,+,,,W4RAT,"Richmond - WCVE Tower",Chesterfield,Virginia,DMR ,1 +146.940000,146.34000,-,74.4,74.4,KN4SKI,"Richmond - VSP",(independent),Virginia,FM Fusion , +145.470000,144.87000,-,94.8,94.8,N3RCN,"Elkton",Cecil,Maryland,FM , +449.775000,444.77500,-,114.8,,N3IOC,"Wyoming",Kent,Delaware,FM , +146.895000,146.29500,-,151.4,151.4,WA4TFZ,"Crozet - Bucks Elbow Mtn",Albemarle,Virginia,FM , +146.655000,146.05500,-,156.7,,K3CRK,"Smyrna",Kent,Delaware,FM , +443.050000,448.05000,+,156.7,,K3CRK,"Smyrna",Kent,Delaware,FM , +449.075000,444.07500,-,,,N3YMS,"Dover",Kent,Delaware,DMR ,1 +448.875000,443.87500,-,100.0,,W3EOC,"Oxford",Chester,Pennsylvania,FM , +442.500000,447.50000,+,100.0,100.0,W3CER,"Middletown - Middletown Emergency",New Castle,Delaware,FM , +441.887500,446.88750,+,,,N3YMS,"Eden",Somerset,Maryland,DMR ,2 +449.725000,444.72500,-,,,N3YMS,"Frederica",Kent,Delaware,DMR ,1 +147.315000,147.91500,+,74.4,74.4,N4POW,"Powhatan - Water Tower",Powhatan,Virginia,FM Fusion WIRES-X , +443.350000,448.35000,+,,,N4POW,"Powhatan - Fighting Creek Park",Powhatan,Virginia,DMR ,1 +446.475000,441.47500,-,114.8,114.8,N3FYI,"Harrisburg - Reesers Summit",York,Pennsylvania,FM AllStar , +146.625000,146.02500,-,156.7,,KA3MRX,"Princess Anne",Somerset,Maryland,FM , +146.790000,146.19000,-,123.0,123.0,W3ZC,"Clearville - Martin Hill",Bedford,Pennsylvania,FM AllStar , +146.460000,147.46000,s,67.0,,N3TWT,"Toboyne - Three Square Hollow",Perry,Pennsylvania,FM EchoLink , +146.925000,146.32500,-,156.7,156.7,W3PRO,"Salisbury",Wicomico,Maryland,FM , +442.650000,447.65000,+,,,N3MRG,"Salisbury",Wicomico,Maryland,DMR ,6 +444.200000,449.20000,+,,,W3PRO,"Salisbury",Wicomico,Maryland,DSTAR , +145.280000,144.68000,-,,,W3PRO,"Salisbury",Wicomico,Maryland,DSTAR , +444.050000,449.05000,+,,156.7,K3RIC,"Salisbury",Wicomico,Maryland,FM Fusion , +449.925000,444.92500,-,123.0,,KA3TKW,"Harrisburg - Reesers Summit",York,Pennsylvania,FM , +146.790000,146.19000,-,,,N3YMS,"Dover - Dover Motor Speedway",Kent,Delaware,DMR ,1 +444.500000,439.50000,-,114.8,,N3IOC,"Dover",Kent,Delaware,FM , +145.130000,144.53000,-,,,W3OR,"Crisfield - McCready Hospital",Somerset,Maryland,DMR ,1 +440.625000,445.62500,+,,,K2VIZ,"Topping",Middlesex,Virginia,DMR ,1 +145.110000,144.51000,-,156.7,156.7,N3RKT,"Crisfield",Somerset,Maryland,FM Fusion WIRES-X , +147.165000,147.76500,+,,,KB3FN,"Cumberland",Allegany,Maryland,FM , +444.000000,449.00000,+,123.0,123.0,KK3L,"Cumberland",Allegany,Maryland,FM , +146.970000,146.37000,-,77.0,77.0,KC3ARC,"Dover - DMV Complex",Kent,Delaware,FM Fusion , +145.290000,144.69000,-,131.8,131.8,KC8MTV,"Waynesboro - Bear Den Mtn",Augusta,Virginia,FM Fusion WIRES-X , +147.015000,147.61500,+,118.8,118.8,W3RRR,"Lancaster - Hospital",Lancaster,Pennsylvania,FM EchoLink , +449.575000,444.57500,-,114.8,114.8,W3RRR,"Lancaster - Hospital",Lancaster,Pennsylvania,FM Fusion WIRES-X , +145.320000,144.72000,-,,,W3OR,"Westover",Somerset,Maryland,FM , +147.075000,147.67500,+,131.8,131.8,W4PNT,"Waynesboro - Bear Den Mtn",Augusta,Virginia,FM , +444.775000,449.77500,+,151.4,,KF4UCI,"Waynesboro - Bear Den Mtn",Augusta,Virginia,FM , +146.685000,146.08500,-,,,N3TWT,"Landisburg",Perry,Pennsylvania,DMR ,1 +145.250000,144.65000,-,114.8,,N3SLC,"Christiana",Lancaster,Pennsylvania,FM Fusion , +145.310000,144.71000,-,141.3,141.3,W3UD,"Newark - U of D",New Castle,Delaware,FM EchoLink , +146.700000,146.10000,-,131.8,131.8,W3DRA,"Newark - Water Tower",New Castle,Delaware,FM Fusion , +449.025000,444.02500,-,131.8,131.8,W3DRA,"Newark - Water Tower",New Castle,Delaware,FM Fusion , +447.875000,442.87500,-,,,K3ZED,"Jennersville - SR 1/SR 796",Chester,Pennsylvania,DMR ,1 +146.880000,146.28000,-,123.0,,W3YMW,"Frostburg - Dans Mtn",Allegany,Maryland,FM , +147.315000,147.91500,+,123.0,,W3YMW,"Frostburg - Dans Mtn",Allegany,Maryland,FM Fusion WIRES-X , +146.925000,146.32500,-,114.8,114.8,K3LPV,"Kelton - 796 &amp; Kelton RD",Chester,Pennsylvania,AllStar DMR ,1 +444.200000,449.20000,+,100.0,100.0,N3VEM,"Witmer",Lancaster,Pennsylvania,FM AllStar , +444.500000,449.50000,+,118.8,,W3YMW,"Frostburg - Dans Mtn",Allegany,Maryland,FM , +146.760000,146.16000,-,151.4,,WA4TFZ,"Covesville - Heard Mtn",Albemarle,Virginia,FM , +441.650000,446.65000,+,,,WR3IRS,"Harrisburg",Dauphin,Pennsylvania,DMR ,1 +145.210000,144.61000,-,123.0,123.0,KA3TKW,"Harrisburg",Dauphin,Pennsylvania,FM IRLP , +146.760000,146.16000,-,100.0,,W3UU,"Harrisburg - Blue Mtn",Dauphin,Pennsylvania,FM , +147.375000,147.97500,+,,,W3ND,"Harrisburg - Blue Mtn",Dauphin,Pennsylvania,DMR ,1 +448.075000,443.07500,-,123.0,,W3ND,"Harrisburg",Dauphin,Pennsylvania,FM , +145.230000,144.63000,-,118.8,118.8,K3IR,"Manheim",Lancaster,Pennsylvania,FM AllStar , +443.300000,448.30000,+,67.0,67.0,N3TWT,"Enola - Blue Mtn",Cumberland,Pennsylvania,FM , +449.675000,444.67500,-,94.8,94.8,WB3LGG,"Cochranville",Chester,Pennsylvania,FM , +449.975000,444.97500,-,114.8,114.8,K3IR,"Manheim",Lancaster,Pennsylvania,FM EchoLink IRLP , +147.360000,147.96000,+,CSQ,CSQ,KA4CBB,"Chester",Chesterfield,Virginia,FM , +442.200000,447.20000,+,131.8,131.8,N3KZ,"Summerdale - East Pennsboro Township",Cumberland,Pennsylvania,FM , +442.750000,447.75000,+,167.9,167.9,AB3FE,"Midland",Allegany,Maryland,FM , +147.390000,147.99000,+,123.0,123.0,WV8BS,"Keyser",Mineral,West Virginia,FM EchoLink Fusion WIRES-X , +444.125000,449.12500,+,103.5,103.5,WV8BS,"Keyser",Mineral,West Virginia,FM Fusion WIRES-X , +147.360000,147.96000,+,127.3,127.3,K7SOB,"Skyline",Grant,West Virginia,FM , +146.850000,146.25000,-,131.8,131.8,KO4CTF,"Verona",Augusta,Virginia,FM , +444.950000,449.95000,+,100.0,100.0,W3CER,"Newark - ChristianaCare",New Castle,Delaware,FM , +449.325000,444.32500,-,173.8,,KA3CNT,"Lititz",Lancaster,Pennsylvania,FM , +449.225000,444.22500,-,131.8,131.8,KA3CNT,"Lititz",Lancaster,Pennsylvania,FM , +444.200000,449.20000,+,123.0,123.0,W3ZC,"Bedford - Kinton Knob",Bedford,Pennsylvania,FM DMR ,1 +145.490000,144.89000,-,123.0,,W3ZC,"Bedford - Kinton Knob",Bedford,Pennsylvania,FM AllStar , +145.210000,144.61000,-,100.0,100.0,WN4HRT,"Gloucester Courthouse - Walter Reed Hospital",Gloucester,Virginia,FM , +145.290000,144.69000,-,123.0,,W3ND,"Harrisburg - Blue Mtn",Dauphin,Pennsylvania,FM IRLP , +145.470000,144.87000,-,123.0,,W3ND,"Harrisburg - Blue Mtn",Dauphin,Pennsylvania,FM , +444.450000,449.45000,+,123.0,123.0,W3ND,"Harrisburg - Blue Mtn",Dauphin,Pennsylvania,FM , +145.370000,144.77000,-,100.0,100.0,W4HZL,"Gloucester Courthouse - WXGM Tower",Gloucester,Virginia,FM , +440.700000,445.70000,+,,,W4TJ,"Williamsburg",(independent),Virginia,DSTAR , +145.160000,144.56000,-,,,W4TJ,"Williamsburg",(independent),Virginia,DSTAR , +447.325000,442.32500,-,,,KI6OM,"Wilmington, DE - Kennett Square",New Castle,Delaware,DSTAR , +449.025000,444.02500,-,,,W3AD,"Cornwall",Lancaster,Pennsylvania,DMR ,1 +146.985000,146.38500,-,100.0,94.8,W3GMS,"Parkesburg",Chester,Pennsylvania,FM AllStar EchoLink , +147.315000,147.91500,+,82.5,82.5,K3LV,"Cornwall",Lancaster,Pennsylvania,FM , +448.825000,443.82500,-,131.8,131.8,N3JLH,"Delaware City",New Castle,Delaware,FM , +146.700000,146.10000,-,131.8,,N4KYM,"Staunton",(independent),Virginia,FM , +443.200000,448.20000,+,156.7,,WS3EOC,"Millsboro",Sussex,Delaware,FM Fusion , +147.090000,147.69000,+,156.7,,WS3ARA,"Millsboro",Sussex,Delaware,FM EchoLink , +449.825000,444.82500,-,156.7,,WS3ARA,"Millsboro",Sussex,Delaware,FM Fusion , +145.390000,144.79000,-,118.8,118.8,W3AD,"Cornwall - Cornwall Mtn",Lancaster,Pennsylvania,FM , +145.170000,144.57000,-,123.0,123.0,KG4TIH,"Staunton - Johnson Street Hill",Augusta,Virginia,FM Fusion WIRES-X , +147.240000,147.84000,+,123.0,,KK3L,"Barton - Big Savage Mtn",Garrett,Maryland,FM Fusion , +444.200000,449.20000,+,123.0,123.0,KG4TIH,"Staunton - Johnson Street Hill",Augusta,Virginia,FM Fusion WIRES-X , +147.105000,147.70500,+,,,KA0JQO,"Cornwall",Lancaster,Pennsylvania,DMR ,1 +145.450000,144.85000,-,100.0,,W3XP,"Ephrata",Lancaster,Pennsylvania,FM , +444.650000,449.65000,+,131.8,,W3XP,"Ephrata",Lancaster,Pennsylvania,FM , +146.625000,146.02500,-,131.8,131.8,N2KEJ,"Woodstown - County EOC",Salem,New Jersey,FM AllStar , +444.937500,449.93750,+,136.5,136.5,WW4GW,"Wintergreen",Nelson,Virginia,FM , +443.700000,448.70000,+,131.8,131.8,N3KZ,"Greenwich",Cumberland,New Jersey,FM , +444.437500,449.43750,+,136.5,136.5,WW4GW,"Wintergreen - Wintergreen Resort",Nelson,Virginia,FM , +147.045000,147.64500,+,114.8,114.8,K3EJ,"Coatesville",Chester,Pennsylvania,FM Fusion , +441.950000,446.95000,+,100.0,100.0,W3EOC,"Coatesville",Chester,Pennsylvania,FM , +146.820000,146.22000,-,136.5,136.5,WW4GW,"Wintergreen - Wintergreen Resort",Nelson,Virginia,FM , +444.550000,449.55000,+,136.5,136.5,WW4GW,"Wintergreen - Wintergreen Resort",Nelson,Virginia,FM , +449.275000,444.27500,-,,,N3TJJ,"Honey Brook",Chester,Pennsylvania,DMR ,1 +443.100000,448.10000,+,,,N3YMS,"Dagsboro",Sussex,Delaware,DMR ,1 +446.475000,441.47500,-,114.8,114.8,N3FYI,"Honey Brook",Chester,Pennsylvania,FM AllStar EchoLink , +147.165000,147.76500,+,82.5,82.5,K3LV,"Grantville - Blue Mtn",Lebanon,Pennsylvania,FM , +147.345000,147.94500,+,179.9,179.9,KC8FPC,"Franklin - North Mtn",Pendleton,West Virginia,FM , +442.000000,447.00000,+,131.8,131.8,N3KZ,"Wilmington",New Castle,Delaware,FM , +146.985000,146.38500,-,,,KE4SCS,"Petersburg",(independent),Virginia,FM Fusion , +444.975000,449.97500,+,74.4,,WA4FC,"Petersburg",(independent),Virginia,FM , +146.955000,146.35500,-,131.8,131.8,W3DRA,"Wilmington",New Castle,Delaware,FM Fusion , +444.400000,449.40000,+,100.0,100.0,W3CER,"Wilmington - ChristianaCare",New Castle,Delaware,FM , +448.425000,443.42500,-,,,WR3IRS,"Wilmington",New Castle,Delaware,DMR ,1 +145.110000,144.51000,-,131.8,131.8,W3ND,"Harrisburg - Ellendale Forge",Dauphin,Pennsylvania,FM , +147.075000,147.67500,+,123.0,,KB3NIA,"Harrisburg - Ellendale",Dauphin,Pennsylvania,FM , +443.550000,448.55000,+,156.7,,W3GMD,"Lewes - WGMD Tower",Sussex,Delaware,FM Fusion , +444.100000,449.10000,+,118.8,118.8,KB4ZIN,"Williamsburg",(independent),Virginia,FM , +147.105000,147.70500,+,118.8,118.8,KB4ZIN,"Williamsburg",(independent),Virginia,FM IRLP , +146.760000,146.16000,-,118.8,118.8,KB4ZIN,"Williamsburg",(independent),Virginia,FM AllStar EchoLink , +444.700000,449.70000,+,,,WC4R,"Williamsburg - I-64/Exit 242",(independent),Virginia,DMR ,1 +441.500000,446.50000,+,123.0,123.0,W3DCW,"Meyersdale - Hays Mill Fire Tower",Somerset,Pennsylvania,FM DMR DSTAR Fusion ,1 +145.270000,144.67000,-,123.0,,KQ3M,"Meyersdale - Hays Mill Fire Tower",Somerset,Pennsylvania,FM AllStar , +447.575000,442.57500,+,,,KD4NFI,"Parksley",Accomack,Virginia,DMR ,1 +444.275000,449.27500,+,103.5,103.5,KG4YJB,"Prince George - South Point Business Park",Prince George,Virginia,FM , +147.045000,147.64500,+,146.2,,K3TAR,"Port Royal - Tuscarora Mtn",Juniata,Pennsylvania,FM , +444.600000,449.60000,+,85.4,85.4,WB3BKN,"Newport",Perry,Pennsylvania,FM , +447.675000,442.67500,-,82.5,82.5,K3LV,"Lebanon",Lebanon,Pennsylvania,FM , +146.880000,146.28000,-,74.4,74.4,W3WAN,"Lebanon",Lebanon,Pennsylvania,FM AllStar , +147.015000,147.61500,+,156.7,,WS3ARA,"Selbyville",Sussex,Delaware,FM Fusion , +447.075000,442.07500,-,123.0,123.0,AA3VI,"Thorndale - Caln Township",Chester,Pennsylvania,FM , +147.390000,147.99000,+,74.4,74.4,WA4FC,"Petersburg",(independent),Virginia,FM , +147.360000,147.96000,-,,,KB4OLM,"Stuarts Draft - Wilda",Augusta,Virginia,FM , +147.330000,147.93000,+,156.7,156.7,W3LRS,"Lewes",Sussex,Delaware,FM DSTAR , +146.490000,147.49000,s,,,W3EOC,"Pocopson",Chester,Pennsylvania,FM , +445.068750,440.06875,-,,,W3EOC,"Pocopson",Chester,Pennsylvania,FM , +146.805000,146.20500,-,123.0,,KB8NUF,"Oakland - Eagle Rock Rd",Garrett,Maryland,FM , +441.825000,446.82500,+,131.8,,K8APD,"Franklin",Pendleton,West Virginia,FM , +443.150000,448.15000,+,,,KF4UCI,"Staunton - Buffalo Gap",Augusta,Virginia,DMR ,1 +444.550000,449.55000,+,123.0,123.0,W3ND,"Newport - Buffalo Mtn",Perry,Pennsylvania,FM , +147.300000,147.90000,+,,,KA0JSW,"Newport",Perry,Pennsylvania,DMR ,1 +147.210000,147.81000,+,,,N4TIK,"Craddockville",Accomack,Virginia,DMR ,1 +444.275000,449.27500,+,100.0,100.0,W4WFF,"Wallops Island - Water Tower",Accomack,Virginia,FM DMR ,1 +146.730000,146.13000,-,131.8,131.8,W3DRA,"Wilmington",New Castle,Delaware,FM , +448.375000,443.37500,-,131.8,131.8,W3DRA,"Wilmington",New Castle,Delaware,FM Fusion , +448.725000,443.72500,-,,,W3BXW,"Roxana",Sussex,Delaware,DMR ,1 +441.950000,446.95000,+,123.0,,KA3TKW,"Harrisburg",Dauphin,Pennsylvania,FM , +147.255000,147.85500,+,156.7,156.7,K4BW,"Accomac",Accomack,Virginia,FM , +444.300000,449.30000,+,,156.7,K4BW,"Accomac",Accomack,Virginia,FM , +442.687500,447.68750,+,,,WA4FC,"Petersburg",(independent),Virginia,DMR ,1 +449.075000,444.07500,-,131.8,,N3SWH,"Newmanstown - Texter Mtn",Lebanon,Pennsylvania,FM Fusion , +147.285000,147.88500,+,131.8,,N3SWH,"Newmanstown - Millcreek Twp",Lebanon,Pennsylvania,FM EchoLink , +146.940000,146.34000,-,131.8,,W3PHL,"West Chester",Chester,Pennsylvania,FM , +446.525000,441.52500,-,100.0,100.0,W3EOC,"West Chester",Chester,Pennsylvania,FM , +443.450000,448.45000,+,151.4,151.4,K3ORB,"Ocean Pines - Ocean Pines water tower",Worcester,Maryland,FM P-25 ,293 +145.190000,144.59000,-,179.9,179.9,N3RCC,"Ocean Pines - Sandyhook Rd Water Tank",Worcester,Maryland,FM , +145.120000,144.52000,-,,,N3QEM,"Rehoboth Beach",Sussex,Delaware,DMR ,1 +443.062500,448.06250,+,,,N3QEM,"Rehoboth Beach",Sussex,Delaware,DMR ,2 +443.400000,448.40000,+,,,WS3EOC,"Rehoboth Beach",Sussex,Delaware,FM , +442.400000,447.40000,+,131.8,131.8,N3KZ,"Robesonia - Eagles Peak Camping Resort",Lebanon,Pennsylvania,FM , +447.275000,442.27500,-,131.8,131.8,N2YIR,"Bridgeton",Cumberland,New Jersey,FM AllStar EchoLink , +146.955000,146.35500,-,114.8,114.8,NW2M,"Ocean Pines",Worcester,Maryland,FM Fusion , +147.135000,147.73500,+,103.5,103.5,KX8T,"Davis",Tucker,West Virginia,FM , +443.150000,448.15000,+,123.0,,N3LZV,"Windber - Shaffer Mtn",Somerset,Pennsylvania,FM , +147.240000,147.84000,+,123.0,123.0,KB3VDL,"Elizabethville - Berry Mtn",Dauphin,Pennsylvania,FM , +446.775000,441.77500,-,88.5,88.5,W3KG,"Boothwyn",Delaware,Pennsylvania,FM , +147.045000,147.64500,+,131.8,131.8,KG4HOT,"Staunton - Elliott Knob",Augusta,Virginia,FM , +444.100000,449.10000,+,131.8,131.8,KG4HOT,"Staunton - Elliott Knob",Augusta,Virginia,FM , +145.310000,144.71000,-,123.0,,W3WIV,"Huntingdon",Huntingdon,Pennsylvania,FM , +146.700000,146.10000,-,123.0,,W3VI,"Huntingdon",Huntingdon,Pennsylvania,FM , +441.300000,446.30000,+,,,WR3IRS,"Eagle",Chester,Pennsylvania,DMR ,1 +441.800000,446.80000,-,100.0,,W3EOC,"Eagle - Upper Uwchlan Township",Chester,Pennsylvania,FM , +145.190000,144.59000,-,123.0,,W3DBB,"Lewistown - Strodes Mills",Mifflin,Pennsylvania,FM , +147.030000,147.63000,+,100.0,CSQ,WT4EN,"Surry",Surry,Virginia,FM , +443.825000,448.82500,+,100.0,CSQ,WT4EN,"Surry",Surry,Virginia,FM DMR ,1 +444.275000,449.27500,+,110.9,,KB3AVZ,"Oakland",Garrett,Maryland,FM , +146.700000,146.10000,-,173.8,,KB3AVZ,"Oakland",Garrett,Maryland,FM , +147.150000,147.75000,+,167.9,167.9,NR3T,"Blue Knob - Ski Resort",Bedford,Pennsylvania,FM AllStar , +442.225000,447.22500,+,CSQ,,NR3T,"Claysburg - State Park",Bedford,Pennsylvania,FM DMR ,1 +443.725000,448.72500,+,127.3,127.3,K3SMT,"Meyersdale - Mt Davis",Somerset,Pennsylvania,FM DMR DSTAR Fusion ,1 +146.760000,146.16000,-,88.5,88.5,W3KKC,"Meyersdale - Mt Davis",Somerset,Pennsylvania,FM AllStar , +147.255000,147.85500,+,179.9,,KC2TXB,"Rosenhayn",Cumberland,New Jersey,FM , +443.300000,448.30000,+,136.5,136.5,WW4GW,"Farmville - Water Tower",Cumberland,Virginia,FM , +146.955000,146.35500,-,136.5,136.5,WW4GW,"Farmville - Water Tower",Cumberland,Virginia,FM , +441.312500,446.31250,+,,,N3YMS,"Bethany Beach",Sussex,Delaware,FM , +147.285000,147.88500,+,103.5,103.5,N8HON,"Circleville - Spruce Knob",Pendleton,West Virginia,FM , +443.575000,448.57500,+,123.0,123.0,KE3UC,"Central City - Statler Hill",Somerset,Pennsylvania,DMR ,1 +146.625000,146.02500,-,123.0,123.0,WR3AJL,"Central City - Statler Hill",Somerset,Pennsylvania,FM AllStar DMR Fusion ,1 +146.910000,146.31000,-,123.0,123.0,K3DNA,"Lewistown",Mifflin,Pennsylvania,FM , +146.940000,146.34000,-,131.8,131.8,W3KG,"Media - Fair Acres",Delaware,Pennsylvania,FM , +441.650000,446.65000,+,,,N9KET,"Fenwick Island",Sussex,Delaware,DMR ,2 +145.170000,144.57000,-,77.0,77.0,N9KET,"Fenwick Island",Sussex,Delaware,FM AllStar , +449.825000,444.82500,-,123.0,,KB3VDL,"Lykens",Dauphin,Pennsylvania,FM , +442.600000,447.60000,+,123.0,,WO3T,"Huntingdon",Huntingdon,Pennsylvania,DMR ,1 +147.195000,147.79500,+,123.0,,K3SMT,"Somerset",Somerset,Pennsylvania,FM EchoLink , +443.250000,448.25000,+,123.0,,K3SMT,"Somerset",Somerset,Pennsylvania,FM , +444.012500,449.01250,+,,,K3ORB,"Ocean City - Seawatch Hotel",Worcester,Maryland,DMR ,1 +146.640000,146.04000,-,103.5,,N8MIN,"Harmon",Randolph,West Virginia,FM , +444.700000,449.70000,+,131.8,131.8,KM3W,"Chester",Delaware,Pennsylvania,FM AllStar EchoLink WIRES-X , +440.550000,445.55000,+,,,N4AR,"Rushmere - Near Lawnes Creek Road and Fort Huger",Isle of Wight,Virginia,DMR DSTAR ,7 +145.170000,144.57000,-,82.5,82.5,AA3RG,"Pine Grove",Schuylkill,Pennsylvania,FM , +146.640000,146.04000,-,82.5,,AA3RG,"Pine Grove",Schuylkill,Pennsylvania,FM AllStar , +448.225000,443.22500,-,82.5,82.5,AA3RG,"Pine Grove",Schuylkill,Pennsylvania,FM , +444.600000,449.60000,+,79.7,,KN4KV,"Yorktown",York,Virginia,DMR ,1 +146.940000,146.34000,-,131.8,,W3AEC,"Media",Delaware,Pennsylvania,FM , +147.345000,147.94500,+,156.7,156.7,KN4GE,"Eastville",Northampton,Virginia,FM , +146.625000,146.02500,-,100.0,100.0,KB3WLV,"Reading",Berks,Pennsylvania,FM AllStar DMR EchoLink NXDN ,1 +440.056250,445.05625,+,,,W3AEC,"Lima - Fair Acres",Delaware,Pennsylvania,DSTAR , +449.625000,444.62500,-,100.0,100.0,K3CX,"Reading",Berks,Pennsylvania,FM , +442.300000,447.30000,-,94.8,94.8,KB3WLV,"Reading",Berks,Pennsylvania,FM AllStar DMR Fusion ,1 +147.300000,147.90000,+,110.9,110.9,KD4ADL,"Lexington - Rocky Mtn",Rockbridge,Virginia,FM , +147.330000,147.93000,+,131.8,CSQ,W4ROC,"Lexington - Rocky Mtn",Rockbridge,Virginia,FM Fusion , +449.625000,444.62500,-,123.0,,W2SCR,"Millville",Cumberland,New Jersey,FM , +147.270000,147.87000,+,77.0,77.0,N3KZ,"Bucktown - South Coventry Township",Chester,Pennsylvania,FM , +145.130000,144.53000,-,131.8,,WB3JOE,"Paoli - Hospital",Chester,Pennsylvania,FM , +445.175000,440.17500,-,,,KB3WLV,"READING",Berks,Pennsylvania,DMR P-25 ,1 +445.081250,440.08125,-,,,KB3SLR,"Bucktown - South Coventry Township",Chester,Pennsylvania,DSTAR , +446.175000,441.17500,-,100.0,,W3EOC,"Bucktown - South Coventry Township",Chester,Pennsylvania,FM , +440.200000,445.20000,+,,,WR3IRS,"Charlestown",Chester,Pennsylvania,DMR ,1 +446.625000,441.62500,-,,,KA3KDL,"Reading",Berks,Pennsylvania,DMR DSTAR NXDN P-25 ,1293 +444.325000,449.32500,+,,,N4HRS,"Farmville - Leigh Mtn",Prince Edward,Virginia,DMR ,9 +145.490000,144.89000,-,114.8,114.8,K3TI,"Reading - Mt Penn",Berks,Pennsylvania,FM Fusion , +147.180000,147.78000,+,110.9,,K2SEH,"Reading - Mt Penn",Berks,Pennsylvania,FM EchoLink , +442.100000,447.10000,+,,,NU3T,"Altoona - Brush Mtn",Blair,Pennsylvania,DMR ,1 +147.060000,147.66000,+,131.8,131.8,WB3JOE,"Newtown Square",Delaware,Pennsylvania,FM , +449.875000,444.87500,-,146.2,146.2,KC2JPP,"Cape May",Cape May,New Jersey,FM , +147.195000,147.79500,+,100.0,,W3DI,"Newtown Square",Delaware,Pennsylvania,FM , +442.250000,447.25000,+,131.8,131.8,W3DI,"Newtown Square",Delaware,Pennsylvania,FM , +441.200000,446.20000,+,,,WR3IRS,"Newtown Square",Delaware,Pennsylvania,DMR ,1 +446.925000,441.92500,-,156.7,,K3SJH,"Reading",Berks,Pennsylvania,FM Fusion , +145.490000,144.89000,-,179.9,,WA2WUN,"Vineland",Cumberland,New Jersey,FM , +446.625000,441.62500,-,94.8,,K2GOD,"Vineland",Cumberland,New Jersey,FM DMR DSTAR Fusion ,1 +147.000000,146.40000,-,103.5,103.5,KC8KCI,"Terra Alta",Preston,West Virginia,FM , +442.900000,447.90000,+,100.0,,W4MT,"Newport News",(independent),Virginia,FM , +441.812500,446.81250,+,,,W4MT,"Newport News",(independent),Virginia,DSTAR , +145.300000,144.70000,-,,,W4MT,"Newport News",(independent),Virginia,DSTAR , +147.180000,147.78000,+,100.0,,WD4ITN,"Monterey - Monterey Mtn",Highland,Virginia,FM EchoLink , +145.490000,144.89000,-,136.5,136.5,K4CQ,"Amherst - Buffalo Ridge",Amherst,Virginia,FM , +147.165000,147.76500,+,100.0,,W4CM,"Newport News",(independent),Virginia,FM , +146.910000,146.31000,-,131.8,,W3BN,"Reading",Berks,Pennsylvania,FM , +146.670000,146.07000,-,173.8,,KG4NJA,"Hampton - NASA Gantry",(independent),Virginia,FM , +443.650000,448.65000,+,173.8,173.8,KG4NJA,"Hampton - NASA Gantry",(independent),Virginia,FM , +146.760000,146.16000,-,131.8,,W3PHL,"Valley Forge - Schuylkill Township",Chester,Pennsylvania,FM , +443.800000,448.80000,+,131.8,131.8,N3KZ,"Valley Forge - Schuylkill Township",Chester,Pennsylvania,FM , +145.410000,144.81000,-,100.0,100.0,WC4R,"Newport News",(independent),Virginia,FM Fusion WIRES-X , +145.210000,144.61000,-,123.0,123.0,N3YFO,"Johnstown",Cambria,Pennsylvania,FM DMR ,1 +444.406250,449.40625,+,,,W3SC,"Joliett",Schuylkill,Pennsylvania,DMR ,1 +440.106250,445.10625,+,,,KD2LNB,"Glassboro - Rowan University",Gloucester,New Jersey,DMR ,1 +446.475000,441.47500,-,114.8,114.8,N3FYI,"Summit Station",Schuylkill,Pennsylvania,FM AllStar EchoLink , +147.000000,146.40000,-,100.0,100.0,WN4HRT,"Newport News - Riverside Reg Med Ctr",(independent),Virginia,FM Fusion , +147.180000,147.78000,+,131.8,131.8,W2MMD,"Pitman",Gloucester,New Jersey,FM EchoLink , +442.750000,447.75000,+,141.3,,KI3I,"Pottstown",Berks,Pennsylvania,FM , +442.100000,447.10000,+,131.8,131.8,W2MMD,"Pitman",Gloucester,New Jersey,FM Fusion , +444.675000,449.67500,+,103.5,,KD8MIV,"Parsons",Tucker,West Virginia,FM Fusion , +440.043750,445.04375,+,,,N3AEC,"Upper Darby - Delaware Co Mem Hospital",Delaware,Pennsylvania,DSTAR , +443.550000,448.55000,+,131.8,131.8,K3ZMC,"Earlville",Berks,Pennsylvania,FM Fusion , +147.210000,147.81000,+,131.8,,K3ZMC,"Earlville",Berks,Pennsylvania,FM , +147.360000,147.96000,+,131.8,131.8,WB3JOE,"Darby - Mercy Fitzgerald Hospital",Delaware,Pennsylvania,FM , +444.050000,449.05000,+,131.8,131.8,WB3JOE,"Darby - Mercy Fitzgerald Hospital",Delaware,Pennsylvania,FM , +443.500000,448.50000,+,,,W4HPT,"Hampton - Sentara Care Plex",(independent),Virginia,DMR ,1 +145.230000,144.63000,-,100.0,100.0,W4MT,"Newport News",(independent),Virginia,FM , +146.670000,146.07000,-,167.9,167.9,WA2WUN,"Wildwood",Cape May,New Jersey,FM Fusion , +447.475000,442.47500,-,,,NJ2DS,"Cape May - Courthouse",Cape May,New Jersey,FM , +147.240000,147.84000,+,146.2,146.2,W2CMC,"Cape May - Courthouse",Cape May,New Jersey,FM , +443.600000,448.60000,+,146.2,146.2,W2CMC,"Cape May - Courthouse",Cape May,New Jersey,FM , +444.550000,449.55000,+,100.0,,W4QR,"Hampton - Executive Towers",(independent),Virginia,FM , +448.125000,443.12500,-,192.8,,KE2CK,"Minotola",Atlantic,New Jersey,FM , +442.175000,447.17500,+,100.0,100.0,N6GVG,"Hampton",(independent),Virginia,FM , +147.120000,147.72000,+,123.0,123.0,KC2DUX,"Woodbury",Gloucester,New Jersey,FM EchoLink , +147.360000,147.96000,+,141.3,141.3,NW2NJ,"North Wildwood",Cape May,New Jersey,FM AllStar , +146.805000,146.20500,-,118.8,,KE2CK,"Minotola",Atlantic,New Jersey,FM , +444.600000,449.60000,+,123.0,,W3VO,"Altoona - Wopsy Ridge",Blair,Pennsylvania,FM , +146.820000,146.22000,-,123.0,,W3QW,"Altoona - Wopsy Ridge",Blair,Pennsylvania,FM AllStar , +146.850000,146.25000,-,146.2,146.2,W3YA,"Boalsburg",Centre,Pennsylvania,FM , +444.850000,449.85000,+,100.0,100.0,K3YV,"Pine Grove Mills",Centre,Pennsylvania,FM Fusion , +146.730000,146.13000,-,100.0,,W4QR,"Hampton - Executive Towers",(independent),Virginia,FM , +145.490000,144.89000,-,100.0,,KE4UP,"Hampton",(independent),Virginia,FM , +147.225000,147.82500,+,,,KA4VXR,"Hampton",(independent),Virginia,DMR ,1 +146.610000,146.01000,-,88.5,,N2CMC,"Woodbine",Cape May,New Jersey,FM , +145.390000,144.79000,-,123.0,123.0,N3YFO,"New Germany",Cambria,Pennsylvania,FM DMR ,1 +442.825000,447.82500,+,123.0,123.0,N3YFO,"Johnstown",Cambria,Pennsylvania,FM DMR ,1 +442.025000,447.02500,+,123.0,123.0,KC3JKJ,"Johnstown",Cambria,Pennsylvania,FM AllStar , +146.835000,146.23500,-,88.5,88.5,AA3E,"Eagleville",Montgomery,Pennsylvania,FM EchoLink , +146.805000,146.20500,-,131.8,,WA3SSG,"Eagleville",Montgomery,Pennsylvania,FM , +442.450000,447.45000,+,131.8,131.8,WA3SSG,"Eagleville",Montgomery,Pennsylvania,FM , +145.200000,144.60000,-,,,W4HPT,"Hampton - City Hall",(independent),Virginia,DSTAR , +444.212500,449.21250,+,,,W4HPT,"Hampton - City Hall",(independent),Virginia,DSTAR , +146.610000,146.01000,-,123.0,123.0,W3QZF,"Altoona - Wopsy Ridge",Blair,Pennsylvania,FM , +146.685000,146.08500,-,146.2,146.2,WM3PEN,"Philadelphia - U of P",Philadelphia,Pennsylvania,FM EchoLink , +147.015000,147.61500,+,127.3,127.3,KA3JSD,"Mount Pleasant - Laurel Mtn",Westmoreland,Pennsylvania,FM , +442.375000,447.37500,+,131.8,,KA3JSD,"Mount Pleasant - Bald Knob",Westmoreland,Pennsylvania,FM , +147.390000,147.99000,+,82.5,82.5,KB3VXB,"Hegins - Landfill",Schuylkill,Pennsylvania,FM DMR DSTAR Fusion ,7 +145.390000,144.79000,-,91.5,,K2DX,"Monroe Township",Gloucester,New Jersey,FM , +444.160000,449.16000,+,82.5,82.5,KB3VXB,"Hegins - Landfill",Schuylkill,Pennsylvania,FM AllStar Fusion WIRES-X , +146.835000,146.23500,-,,,W3WGX,"Seven Springs",Somerset,Pennsylvania,DMR ,1 +443.925000,448.92500,+,123.0,,KB9WCX,"Seven Springs",Somerset,Pennsylvania,FM AllStar , +448.675000,443.67500,-,131.8,131.8,N3CB,"Norristown",Montgomery,Pennsylvania,FM , +147.195000,147.79500,+,136.5,136.5,WA4RTS,"Lynchburg - Tobacco Row Mtn",Amherst,Virginia,FM EchoLink , +444.500000,449.50000,+,136.5,136.5,K4CQ,"Lynchburg - Tobacco Row Mtn",Amherst,Virginia,FM , +146.655000,146.05500,-,,,WA4RTS,"Lynchburg - Tobacco Row Mtn",Amherst,Virginia,DMR ,1 +443.550000,448.55000,+,,,N4HRS,"Lynchburg - Tobacco Row Mtn",Amherst,Virginia,DMR ,9 +440.512500,445.51250,+,,,K4LCT,"Hampton",(independent),Virginia,DMR ,7 +447.775000,442.77500,-,146.2,,NJ2GC,"Gloucester City",Camden,New Jersey,FM Fusion , +444.950000,449.95000,+,136.5,136.5,WD4KQI,"Lynchburg - Tobacco Row Mtn",Amherst,Virginia,FM Fusion WIRES-X , +444.890000,449.89000,+,241.8,,K3REY,"Philadelphia",Philadelphia,Pennsylvania,FM , +145.270000,144.67000,-,,,W3PVI,"Philadelphia",Philadelphia,Pennsylvania,DMR ,2 +145.410000,144.81000,-,127.3,,KD3WT,"Philadelphia",Philadelphia,Pennsylvania,FM AllStar , +442.400000,447.40000,+,131.8,131.8,N3KZ,"Philadelphia",Philadelphia,Pennsylvania,FM , +442.550000,447.55000,+,91.5,91.5,W3SBE,"Philadelphia - Roxborough Towers",Philadelphia,Pennsylvania,FM , +442.800000,447.80000,+,131.8,,K3TU,"Philadelphia",Philadelphia,Pennsylvania,FM , +446.875000,441.87500,-,131.8,131.8,KD3WT,"Philadelphia",Philadelphia,Pennsylvania,FM Fusion , +147.015000,147.61500,+,100.0,100.0,WN4HRT,"Smithfield - Riverside Hospital",Isle of Wight,Virginia,FM Fusion , +444.475000,449.47500,+,123.0,,NJ3T,"Jennerstown - Above Old Roaring Run Scout Camp",Somerset,Pennsylvania,FM , +147.375000,147.97500,+,123.0,CSQ,N3LZX,"Jennerstown - Roaring Run",Somerset,Pennsylvania,FM , +146.820000,146.22000,-,91.5,91.5,N8OYY,"Rowlesburg - Top Laurel Mtn",Preston,West Virginia,FM , +147.195000,147.79500,+,100.0,100.0,WT4RA,"Smithfield - Courthouse",Isle of Wight,Virginia,FM EchoLink Fusion , +442.825000,447.82500,+,100.0,,WT4RA,"Smithfield - Courthouse",Isle of Wight,Virginia,FM EchoLink Fusion , +147.225000,147.82500,+,192.8,192.8,WA2WUN,"Runnemede",Camden,New Jersey,FM Fusion , +441.700000,446.70000,+,74.4,74.4,W3WAN,"Roxborough",Philadelphia,Pennsylvania,FM AllStar , +440.650000,445.65000,+,,,WR3IRS,"Philadelphia - Roxborough Towers",Philadelphia,Pennsylvania,DMR ,1 +444.300000,449.30000,+,131.8,,WB3EHB,"Camden",Camden,New Jersey,FM , +448.025000,443.02500,-,131.8,,N2HQX,"Camden",Camden,New Jersey,FM , +147.030000,147.63000,+,91.5,91.5,W3QV,"Philadelphia",Philadelphia,Pennsylvania,FM AllStar EchoLink , +440.093750,445.09375,+,,,NJ2CM,"Ocean View",Cape May,New Jersey,DSTAR , +145.270000,144.67000,-,136.5,,KF4YLM,"Lynchburg - Tobacco Row Mtn",Amherst,Virginia,FM EchoLink , +443.500000,448.50000,+,D712,D712,N4HRS,"Lynchburg - Tobacco Row Mtn",Amherst,Virginia,FM , +147.360000,147.360000,x,,,KR4HVV,"Kenbridge - Old America Gas Building",Lunenburg,Virginia,DMR ,2 +147.180000,147.78000,+,100.0,100.0,K3SNY,"Selinsgrove - Selinsgrove Center",Snyder,Pennsylvania,FM , +145.210000,144.61000,-,162.2,,KF8LO,"Elkins",Randolph,West Virginia,FM , +146.745000,146.14500,-,103.5,,KF8LO,"Elkins",Randolph,West Virginia,FM , +146.775000,146.17500,-,CSQ,,NE8W,"Elkins",Randolph,West Virginia,FM , +442.100000,447.10000,+,162.2,,KD8JCS,"Elkins - Rich Mtn",Randolph,West Virginia,FM AllStar , +444.850000,449.85000,+,162.2,,N8RLR,"Elkins",Randolph,West Virginia,FM , +440.400000,445.40000,+,,,WR3IRS,"Corbin City",Atlantic,New Jersey,DMR ,1 +146.865000,146.26500,-,131.8,,K2UK,"Pine Hill",Camden,New Jersey,FM , +442.350000,447.35000,+,131.8,,K2UK,"Pine Hill",Camden,New Jersey,FM , +145.450000,144.85000,-,146.2,146.2,K3CR,"State College - Penn State University",Centre,Pennsylvania,FM , +443.650000,448.65000,+,146.2,146.2,K3CR,"State College",Centre,Pennsylvania,FM , +146.940000,146.34000,-,123.0,,NW3F,"Johnstown - Laurel Mtn",Cambria,Pennsylvania,FM AllStar EchoLink , +444.393750,449.39375,+,,,W3SC,"Pottsville",Schuylkill,Pennsylvania,DMR ,1 +442.987500,447.98750,+,,,AB8E,"Elkins - Rich Mtn",Randolph,West Virginia,DMR ,1 +441.925000,446.92500,+,,,W4DHW,"Lexington - Brushy Hill",Rockbridge,Virginia,DMR ,1 +146.625000,146.02500,-,100.0,100.0,N4LLE,"Jarrett",Sussex,Virginia,FM , +444.800000,449.80000,+,,,KE3UC,"Johnstown - Chickaree Mtn",Cambria,Pennsylvania,DMR ,1 +146.475000,147.47000,s,131.8,131.8,W3TWA,"Pottsville - Avenues",Schuylkill,Pennsylvania,FM , +145.430000,144.83000,-,123.0,123.0,ND3L,"Ebensburg - Pendleton Ridge",Cambria,Pennsylvania,FM , +447.625000,442.62500,-,,,K3PDR,"Wyndmoor - Whitemarsh",Montgomery,Pennsylvania,DMR ,1 +146.610000,146.01000,-,,,K3PDR,"Wyndmoor",Montgomery,Pennsylvania,DSTAR , +445.181250,440.18125,-,,,K3PDR,"Wyndmoor",Montgomery,Pennsylvania,DSTAR , +145.230000,144.63000,-,103.5,103.5,KX8T,"Belington",Barbour,West Virginia,FM AllStar , +449.125000,444.12500,-,88.5,88.5,AA3E,"Eagleville",Montgomery,Pennsylvania,FM Fusion , +145.370000,144.77000,-,91.5,91.5,NJ2CH,"Cherry Hill",Camden,New Jersey,FM Fusion , +444.900000,449.90000,+,131.8,,K3RJC,"Cherry Hill",Camden,New Jersey,FM Fusion , +146.895000,146.29500,-,91.5,91.5,K2EOC,"Voorhees",Camden,New Jersey,FM , +147.120000,147.72000,+,131.8,131.8,W3VPJ,"Paxinos",Northumberland,Pennsylvania,FM , +145.150000,144.55000,-,91.5,91.5,K2AX,"Winslow",Camden,New Jersey,FM , +444.875000,449.87500,+,162.2,162.2,N2BDP,"Hammonton",Atlantic,New Jersey,FM AllStar EchoLink , +147.345000,147.94500,+,127.3,127.3,WA3BXW,"Waterford Works",Camden,New Jersey,FM , +442.300000,447.30000,+,131.8,131.8,KA2PFL,"Waterford Works",Camden,New Jersey,FM , +443.300000,448.30000,+,,,WR3IRS,"Waterford Works",Camden,New Jersey,DMR ,1 +444.350000,449.35000,+,,,KX8T,"Belington",Barbour,West Virginia,DMR ,1 +145.210000,144.61000,-,D174,D174,W2FLY,"Waterford Works",Camden,New Jersey,FM , +442.700000,447.70000,+,131.8,131.8,N3KZ,"Waterford Works",Camden,New Jersey,FM , +147.375000,147.97500,+,131.8,131.8,W4VB,"Norfolk",(independent),Virginia,FM , +145.170000,144.57000,-,131.8,131.8,WB3JNP,"Connellsville - Rich Hill",Fayette,Pennsylvania,FM , +147.330000,147.93000,+,162.2,,WA3RYQ,"Hatfield",Montgomery,Pennsylvania,FM , +147.045000,147.64500,+,131.8,131.8,W3PIE,"Hopwood - Summit Mtn",Fayette,Pennsylvania,FM , +441.150000,446.15000,+,88.5,CSQ,K3DN,"Abington - Hospital",Montgomery,Pennsylvania,FM , +146.655000,146.05500,-,107.2,107.2,KC3FIT,"Sunbury - Areffe Knob",Northumberland,Pennsylvania,FM Fusion , +443.750000,448.75000,+,131.8,131.8,W3PIE,"Hopwood - Summit Mtn",Fayette,Pennsylvania,FM Fusion WIRES-X , +146.580000,146.580000,x,103.5,,KD8OHG,"Mill Creek",Randolph,West Virginia,FM EchoLink , +145.190000,144.59000,-,131.8,131.8,N3ZA,"Franconia",Montgomery,Pennsylvania,FM Fusion , +146.925000,146.32500,-,103.5,103.5,K8MCR,"Morgantown - Sand Springs Lookout",Preston,West Virginia,FM EchoLink , +147.075000,147.67500,+,103.5,103.5,KX8T,"Morgantown - Sand Springs",Monongalia,West Virginia,FM , +442.600000,447.60000,+,103.5,103.5,K8MCR,"Morgantown - Chestnut Ridge",Monongalia,West Virginia,FM Fusion , +145.430000,144.83000,-,103.5,103.5,W8MWA,"Morgantown - WVPM Tower",Preston,West Virginia,FM Fusion , +146.610000,146.01000,-,136.5,CSQ,N3OG,"Lynchburg - Candlers Mtn",Campbell,Virginia,FM , +442.600000,447.60000,+,136.5,,N3OG,"Lynchburg - Candlers Mtn",Campbell,Virginia,FM , +442.400000,447.40000,+,107.2,107.2,KF4YI,"Lynchburg - Jack Mtn",Campbell,Virginia,FM , +147.105000,147.70500,+,,,K3ARL,"Bellefonte",Centre,Pennsylvania,DMR ,1 +445.625000,440.62500,-,127.3,127.3,K2CPD,"Cinnaminson",Burlington,New Jersey,FM , +146.955000,146.35500,-,123.0,123.0,W3SC,"Saint Clair - Burma Rd",Schuylkill,Pennsylvania,FM , +147.345000,147.94500,+,123.0,123.0,W3SC,"Joliett - Porter Township",Schuylkill,Pennsylvania,FM , +145.170000,144.57000,-,131.8,131.8,WA4ZUA,"Chesapeake",(independent),Virginia,FM , +145.110000,144.51000,-,107.2,107.2,N8RV,"Frost",Pocahontas,West Virginia,FM , +146.790000,146.19000,-,100.0,100.0,N4SD,"Suffolk - Old WTKR Tower",(independent),Virginia,FM IRLP Fusion , +146.715000,146.11500,-,131.8,,K3UTI,"Meadowbrook",Montgomery,Pennsylvania,FM , +443.150000,448.15000,+,131.8,,K3UTI,"Meadowbrook",Montgomery,Pennsylvania,FM , +145.330000,144.73000,-,131.8,131.8,W4VB,"Norfolk - Downtown",(independent),Virginia,FM EchoLink , +442.950000,447.95000,+,131.8,,W4VB,"Norfolk - Downtown",(independent),Virginia,FM EchoLink , +448.775000,443.77500,-,146.2,146.2,K2BR,"Egg Harbor Township - Atlantic County EOC",Atlantic,New Jersey,FM AllStar Fusion , +146.745000,146.14500,-,146.2,146.2,K2BR,"Egg Harbor Township - Atlantic County EOC",Atlantic,New Jersey,FM AllStar EchoLink Fusion , +146.490000,147.49000,s,131.8,131.8,WC3PS,"Derry - Bear Cave Lookout",Westmoreland,Pennsylvania,FM DMR DSTAR NXDN P-25 Fusion , +442.275000,447.27500,+,131.8,131.8,KE3PO,"Derry - Bear Cave Lookout",Westmoreland,Pennsylvania,FM DMR DSTAR NXDN P-25 , +444.550000,449.55000,+,100.0,,WA3TSW,"Horsham - Horsham Township",Montgomery,Pennsylvania,FM , +147.225000,147.82500,+,151.4,151.4,WA3VHL,"Allentown",Lehigh,Pennsylvania,FM Fusion WIRES-X , +147.075000,147.67500,+,100.0,,KC2HTT,"Norfolk - Waterfront",(independent),Virginia,FM Fusion , +447.875000,442.87500,-,,,WA3PNY,"Allentown - Salisbury Twp",Lehigh,Pennsylvania,DMR ,2 +447.625000,442.62500,-,131.8,131.8,W3PLG,"Allentown - Salisbury Twp",Lehigh,Pennsylvania,FM Fusion WIRES-X , +146.850000,146.25000,-,100.0,100.0,W4POX,"Portsmouth - Naval Hospital",(independent),Virginia,FM , +442.450000,447.45000,+,100.0,100.0,KC2HTT,"Norfolk - Waterfront",(independent),Virginia,FM Fusion , +449.775000,444.77500,-,131.8,131.8,W3TWA,"Barnesville - Mtn Valley Golf Course",Schuylkill,Pennsylvania,FM AllStar , +448.625000,443.62500,-,131.8,,WA3UNG,"Ocean City",Cape May,New Jersey,FM , +443.425000,448.42500,+,107.2,107.2,K3HOT,"State College - Rattlesnake mnt",Centre,Pennsylvania,FM EchoLink , +147.165000,147.76500,+,91.5,91.5,AG2NJ,"Egg Harbor City",Atlantic,New Jersey,FM , +146.625000,146.02500,-,110.9,,K3FLT,"Lewisburg",Union,Pennsylvania,FM , +444.700000,449.70000,+,114.8,114.8,N3EB,"State College - Black Moshannon Mtn",Centre,Pennsylvania,FM , +444.475000,449.47500,+,74.4,74.4,W4VB,"Norfolk - Fire Sta 10",(independent),Virginia,FM , +146.430000,147.43000,s,173.8,173.8,W3PHB,"Philipsburg - Rattlesnake Fire Tower",Centre,Pennsylvania,FM EchoLink , +146.760000,146.16000,-,146.2,146.2,W3GA,"State College",Centre,Pennsylvania,FM , +146.775000,146.17500,-,123.0,,N3LAD,"Barnesboro - WNCC Tower",Cambria,Pennsylvania,FM , +146.805000,146.20500,-,107.2,,W4COV,"Covington - Warm Springs Mtn",Bath,Virginia,FM , +146.970000,146.37000,-,91.5,91.5,KF4YLM,"Covington - Warm Springs Mtn",Bath,Virginia,FM EchoLink , +442.250000,447.25000,+,100.0,,WA4PGI,"Covington - Warm Springs Mtn",Bath,Virginia,FM , +440.850000,445.85000,+,,,KC3DVR,"Northern Cambria",Cambria,Pennsylvania,DMR P-25 ,1293 +443.875000,448.87500,+,167.9,,N3LAD,"Northern Cambria",Cambria,Pennsylvania,FM , +145.150000,144.55000,-,131.8,131.8,W3CRC,"Derry - Bear Cave",Westmoreland,Pennsylvania,FM DMR DSTAR NXDN P-25 Fusion , +147.090000,147.69000,+,131.8,,K3DN,"Warminster - Township Bldg",Bucks,Pennsylvania,FM EchoLink , +442.025000,447.02500,+,131.8,131.8,WA3UVV,"Uniontown",Fayette,Pennsylvania,FM Fusion , +145.290000,144.69000,-,151.4,151.4,KC3OVW,"Liberty",Montour,Pennsylvania,FM EchoLink , +145.310000,144.71000,-,131.8,,W3AI,"Perkasie",Bucks,Pennsylvania,FM , +443.950000,448.95000,+,131.8,,K3DN,"Hilltown",Bucks,Pennsylvania,FM Fusion , +145.330000,144.73000,-,131.8,,W3HJ,"Hilltown",Bucks,Pennsylvania,FM , +147.390000,147.99000,+,100.0,,W3HJ,"Hilltown",Bucks,Pennsylvania,FM , +145.370000,144.77000,-,186.2,,KC4RBA,"Forest",Bedford,Virginia,FM , +145.150000,144.55000,-,103.5,,KF8LO,"Philippi",Barbour,West Virginia,FM , +441.843750,446.84375,+,,,K3BUX,"Hilltown",Bucks,Pennsylvania,DMR ,1 +442.900000,447.90000,+,123.0,,W3HJ,"Hilltown",Bucks,Pennsylvania,FM , +145.290000,144.69000,-,91.5,91.5,K2AA,"Medford",Burlington,New Jersey,FM Fusion WIRES-X , +146.670000,146.07000,-,103.5,103.5,KX8T,"Valley Head",Randolph,West Virginia,FM , +146.790000,146.19000,-,131.8,131.8,W3SK,"Southampton",Bucks,Pennsylvania,FM , +448.225000,443.22500,-,131.8,131.8,W3SK,"Southampton",Bucks,Pennsylvania,FM Fusion , +146.745000,146.14500,-,131.8,,N4WFU,"Franklin",(independent),Virginia,FM , +147.270000,147.87000,+,131.8,,WT4FB,"Franklin",(independent),Virginia,FM , +447.775000,442.77500,-,162.2,162.2,KA3ZAT,"Orefield - Leather Corner Post",Lehigh,Pennsylvania,FM , +444.600000,449.60000,+,151.4,151.4,KC3VAU,"Lewisburg",Union,Pennsylvania,FM DMR ,1 +147.270000,147.87000,+,100.0,100.0,KC3VAU,"Lewisburg",Union,Pennsylvania,FM DMR ,1 +147.330000,147.93000,+,123.0,123.0,KD8FDD,"Fairmont - Bunners Ridge",Marion,West Virginia,FM AllStar , +147.375000,147.97500,+,103.5,,W8SLH,"Grafton",Taylor,West Virginia,FM , +444.750000,449.75000,+,118.8,,W8SLH,"Grafton",Taylor,West Virginia,FM , +449.475000,444.47500,-,CSQ,,K2UWC,"Quakertown",Bucks,Pennsylvania,FM AllStar DMR ,1 +444.750000,449.75000,+,103.5,103.5,W3AI,"Sellersville",Bucks,Pennsylvania,FM Fusion , +146.610000,146.01000,-,162.2,,W4CAR,"Chesapeake - Bowers Hill",(independent),Virginia,FM Fusion , +448.975000,443.97500,-,123.0,123.0,KD2KVZ,"Egg Harbor Township",Atlantic,New Jersey,FM , +146.895000,146.29500,-,141.3,CSQ,W4KXV,"Virginia Beach",(independent),Virginia,FM , +444.950000,449.95000,+,141.3,CSQ,W4KXV,"Virginia Beach - Town Center",(independent),Virginia,FM , +146.685000,146.08500,-,100.0,100.0,WA1ZMS,"Bedford - Apple Orchard Mtn",Bedford,Virginia,FM , +442.650000,447.65000,+,100.0,100.0,WA1ZMS,"Bedford - Apple Orchard Mtn",Bedford,Virginia,FM DMR ,1 +145.470000,144.87000,-,82.5,,W4CMH,"South Hill - Community Mem Hospital",Mecklenburg,Virginia,FM , +445.925000,440.92500,-,91.5,91.5,K4MTP,"Bloomsburg - Catawissa Mtn",Columbia,Pennsylvania,FM AllStar , +441.925000,446.92500,+,,,KD8YNY,"Morgantown",Monongalia,West Virginia,DMR Fusion ,1 +145.370000,144.77000,-,123.0,123.0,W3SC,"Delano - Park Place",Schuylkill,Pennsylvania,FM , +146.490000,147.49000,s,131.8,131.8,W3TWA,"Tamaqua - High Rise",Schuylkill,Pennsylvania,FM Fusion , +146.970000,146.37000,-,141.3,,W4KXV,"Virginia Beach - Fire Sta 10",(independent),Virginia,FM , +147.225000,147.82500,+,85.4,85.4,KT3A,"Bloomsburg - Catawissa Mtn",Columbia,Pennsylvania,FM , +444.950000,449.95000,+,88.5,88.5,W3SC,"Delano",Schuylkill,Pennsylvania,FM , +442.237500,447.23750,+,,,WB4JCX,"Virginia Beach - Mt Trashmore",(independent),Virginia,DMR ,1 +146.925000,146.32500,-,131.8,131.8,WB2YGO,"Willingboro",Burlington,New Jersey,FM , +442.050000,447.05000,+,118.8,,WB2YGO,"Willingboro",Burlington,New Jersey,FM , +440.256250,445.25625,+,,,W3TWA,"Delano - Bears Head Fire Tower",Schuylkill,Pennsylvania,DMR ,7 +146.895000,146.29500,-,D131,D131,W3TWA,"Delano - Bears Head Fire Tower",Schuylkill,Pennsylvania,FM AllStar EchoLink , +145.350000,144.75000,-,131.8,,WA3EPA,"Doylestown",Bucks,Pennsylvania,FM , +443.590000,448.59000,+,151.4,,W3LR,"Coopersburg",Lehigh,Pennsylvania,FM AllStar EchoLink , +145.150000,144.55000,-,103.5,,W4FOS,"Chesapeake",(independent),Virginia,FM , +146.985000,146.38500,-,110.9,,K3FLT,"Milton",Northumberland,Pennsylvania,FM , +444.125000,449.12500,+,,,WA4FC,"South Hill",Mecklenburg,Virginia,DMR ,1 +443.525000,448.52500,+,100.0,,KB2AHZ,"South Hill",Mecklenburg,Virginia,FM EchoLink IRLP , +443.125000,448.12500,+,,,K4MJO,"South Hill",Mecklenburg,Virginia,DMR ,6 +443.675000,448.67500,-,123.0,,N3CRK,"Point Marion",Fayette,Pennsylvania,FM , +444.375000,449.37500,+,D712,D712,N4HRS,"Covington - Warm Springs Mtn",Bath,Virginia,FM , +147.240000,147.84000,+,74.4,74.4,WA4FC,"South Hill",Mecklenburg,Virginia,FM , +445.331250,440.33125,-,127.3,127.3,KC2QVT,"Tabernacle - Emergency Svcs Bldg",Burlington,New Jersey,FM Fusion , +147.000000,147.60000,+,77.0,77.0,KB2AHZ,"South Hill",Mecklenburg,Virginia,FM EchoLink IRLP , +146.985000,146.38500,-,146.2,,W2HRW,"West Atlantic City",Atlantic,New Jersey,FM , +443.250000,448.25000,+,146.2,,W2HRW,"West Atlantic City",Atlantic,New Jersey,FM Fusion , +448.975000,443.97500,-,151.4,151.4,KA3NRJ,"Salisbury",Lehigh,Pennsylvania,FM Fusion , +444.100000,449.10000,+,151.4,151.4,KA3NRJ,"Allentown - South Mtn",Lehigh,Pennsylvania,FM AllStar EchoLink , +147.135000,147.73500,+,D315,D315,W3OI,"Allentown - South Mtn",Lehigh,Pennsylvania,FM Fusion WIRES-X , +444.787500,449.78750,+,,,K4MJO,"Lacrosse",Mecklenburg,Virginia,DMR ,2 +442.350000,447.35000,+,,,K4MJO,"Lacrosse",Mecklenburg,Virginia,DMR WIRES-X ,4 +448.325000,443.32500,-,127.3,127.3,KC2QVT,"Westampton",Burlington,New Jersey,DMR IRLP ,1 +147.150000,147.75000,+,127.3,127.3,KC2QVT,"Westampton",Burlington,New Jersey,FM , +147.210000,147.81000,+,123.0,,N2HQX,"Absecon",Atlantic,New Jersey,FM , +442.920000,447.92000,+,110.9,,N2LXJ,"Absecon",Atlantic,New Jersey,FM , +147.300000,147.90000,+,100.0,100.0,WN4HRT,"Virginia Beach",(independent),Virginia,FM , +145.200000,144.60000,-,100.0,100.0,KE4HGP,"Virginia Beach",(independent),Virginia,FM Fusion , +443.500000,448.50000,+,131.8,131.8,W3JPA,"Allentown",Lehigh,Pennsylvania,FM AllStar , +146.760000,146.16000,-,103.5,103.5,W8CUL,"Morgantown - WVU",Monongalia,West Virginia,FM Fusion , +440.637500,445.63750,+,,,W8CUL,"Morgantown - WVU",Monongalia,West Virginia,DMR ,1 +443.150000,448.15000,+,123.0,,KD8FDD,"Grafton - Valley Falls",Taylor,West Virginia,FM , +443.350000,448.35000,+,100.0,100.0,N3XG,"Allentown - Scholl Woodlands Preserve",Lehigh,Pennsylvania,FM AllStar EchoLink , +448.775000,443.77500,-,131.8,131.8,N3MFT,"Allentown",Lehigh,Pennsylvania,FM P-25 ,293 +441.600000,446.60000,+,,,N3RPV,"Allentown",Lehigh,Pennsylvania,DMR ,1 +445.025000,440.02500,-,,,W3OI,"Allentown",Lehigh,Pennsylvania,DSTAR , +147.165000,147.76500,+,,,W3OI,"Allentown",Lehigh,Pennsylvania,DSTAR , +444.150000,449.15000,+,131.8,131.8,N3KZ,"Allentown - Salisbury Twp",Lehigh,Pennsylvania,FM , +449.400000,444.40000,-,D023,D023,N3VKK,"Allentown",Lehigh,Pennsylvania,FM Fusion WIRES-X , +146.820000,146.22000,-,162.2,162.2,W4CAR,"Chesapeake - Greenbriar",(independent),Virginia,FM Fusion , +444.000000,449.00000,+,162.2,162.2,W4CAR,"Chesapeake - Greenbriar",(independent),Virginia,FM Fusion WIRES-X , +443.000000,448.00000,+,162.2,162.2,W1LA,"Whitehall",Lehigh,Pennsylvania,FM Fusion WIRES-X , +442.737500,447.73750,+,,,WB4JCX,"Virginia Beach - VB Oceanfront",(independent),Virginia,DMR , +441.400000,446.40000,+,131.8,131.8,KC2LHJ,"Allentown",Lehigh,Pennsylvania,FM , +145.350000,144.75000,-,103.5,CSQ,W8SP,"Fairmont - Valley Falls State Park",Marion,West Virginia,FM , +145.150000,144.55000,-,103.5,103.5,K4AMG,"Chesapeake",(independent),Virginia,FM EchoLink Fusion WIRES-X , +442.150000,447.15000,+,131.8,131.8,WC3PS,"Greensburg - Westmoreland County 911",Westmoreland,Pennsylvania,FM DMR DSTAR NXDN P-25 Fusion ,1293 +449.725000,444.72500,-,136.5,,N3EXA,"Plumstead",Bucks,Pennsylvania,FM , +447.975000,442.97500,-,127.3,,KB3AJF,"Plumsteadville",Bucks,Pennsylvania,FM , +441.775000,446.77500,+,123.0,123.0,KD8FDD,"Fairmont",Marion,West Virginia,FM AllStar , +146.940000,146.34000,-,71.9,,W3OI,"Allentown - Lehigh Mtn",Lehigh,Pennsylvania,FM , +447.712500,442.71250,-,,,W3PLG,"Bethlehem - South Mtn",Lehigh,Pennsylvania,DSTAR , +442.575000,447.57500,+,131.8,,N3HOM,"New Stanton",Westmoreland,Pennsylvania,FM , +147.030000,147.63000,+,103.5,103.5,N8ZAR,"Buckhannon",Upshur,West Virginia,FM , +145.440000,144.84000,-,,,WC3PS,"Greensburg",Westmoreland,Pennsylvania,DMR DSTAR Fusion ,1 +442.925000,447.92500,+,131.8,131.8,WR3B,"Greensburg",Westmoreland,Pennsylvania,FM Fusion , +444.350000,449.35000,+,107.2,,AA2BP,"Atlantic City",Atlantic,New Jersey,FM , +146.880000,146.28000,-,91.5,,KA2HQP,"Atlantic City",Atlantic,New Jersey,FM , +445.231250,440.23125,-,,,K2ACY,"Atlantic City",Atlantic,New Jersey,DMR ,1 +441.100000,446.10000,+,D156,D023,KC2ABV,"Catasauqua",Lehigh,Pennsylvania,FM AllStar DMR EchoLink IRLP Fusion WIRES-X ,1 +444.975000,449.97500,+,131.8,,W3BMD,"Indiana - 911 Center",Indiana,Pennsylvania,FM DMR Fusion ,1 +146.910000,146.31000,-,131.8,,W3BMD,"Indiana - 911 Center",Indiana,Pennsylvania,FM , +147.300000,147.90000,+,131.8,131.8,W3BXW,"Fairless Hills",Bucks,Pennsylvania,FM , +447.125000,442.12500,-,,,W3BXW,"Fairless Hills",Bucks,Pennsylvania,DMR ,1 +438.500000,433.50000,-,,,W3NTT,"Slatington",Lehigh,Pennsylvania,DMR ,1 +145.410000,144.81000,-,103.5,103.5,W8LD,"Buckhannon - West Virginia Wesleyan College",Upshur,West Virginia,FM EchoLink , +146.850000,146.25000,-,103.5,,KF8LO,"Buckhannon",Upshur,West Virginia,FM Fusion , +442.675000,447.67500,+,103.5,,W8LD,"Buckhannon",Upshur,West Virginia,FM , +444.250000,449.25000,+,103.5,,N8ZAR,"Buckhannon",Upshur,West Virginia,FM AllStar EchoLink , +145.250000,144.65000,-,,,KX8T,"Buckhannon",Upshur,West Virginia,FM Fusion , +445.175000,440.17500,-,100.0,100.0,KC2ABV,"Bethlehem",Northampton,Pennsylvania,FM EchoLink , +443.875000,448.87500,+,103.5,,W8SP,"Fairmont",Marion,West Virginia,FM , +447.575000,442.57500,-,156.7,156.7,K2ACY,"Brigantine Island",Atlantic,New Jersey,FM EchoLink IRLP , +447.525000,442.52500,-,,,KC2TGB,"Brigantine",Atlantic,New Jersey,DSTAR , +146.715000,146.11500,-,91.5,,KA2OOR,"Brigantine",Atlantic,New Jersey,FM , +147.090000,147.69000,+,162.2,,KC8CSE,"Marlinton - WDMT Tower",Pocahontas,West Virginia,FM EchoLink , +146.670000,146.07000,-,131.8,,N3QZU,"Jeannette",Westmoreland,Pennsylvania,FM Fusion , +444.075000,449.07500,+,131.8,131.8,N3QZU,"Jeannette",Westmoreland,Pennsylvania,FM Fusion , +147.360000,147.96000,+,173.8,173.8,KE4MHE,"Lock Haven - Avis",Clinton,Pennsylvania,FM AllStar EchoLink , +449.375000,444.37500,-,131.8,131.8,W3EPE,"Palmerton - Blue Mtn",Carbon,Pennsylvania,FM , +449.650000,444.65000,-,127.3,127.3,K3IHI,"Bethlehem",Northampton,Pennsylvania,FM AllStar EchoLink , +146.745000,146.14500,-,131.8,131.8,WB3CGY,"Ernest - Blue Spruce Co Park",Indiana,Pennsylvania,FM , +444.625000,449.62500,+,,,W3CPA,"Clearfield",Clearfield,Pennsylvania,DMR ,1 +446.375000,441.37500,-,103.5,,KC3RIP,"Jim Thorpe - Pocono Raceway",Carbon,Pennsylvania,FM , +147.120000,147.72000,+,118.8,CSQ,W8SLH,"Bridgeport",Harrison,West Virginia,FM , +146.730000,146.13000,-,151.4,,W3AVK,"Williamsport - Bald Eagle Mtn",Lycoming,Pennsylvania,FM , +145.110000,144.51000,-,131.8,,KA3FLU,"California",Washington,Pennsylvania,FM , +147.360000,147.96000,+,173.8,173.8,NC3PA,"Lock Haven - Swissdale",Clinton,Pennsylvania,FM AllStar EchoLink , +442.300000,447.30000,+,,,WR3IRS,"Scranton",Lackawanna,Pennsylvania,DMR ,1 +444.600000,449.60000,+,156.7,CSQ,N3MSK,"Easton - Gaffney Hill",Northampton,Pennsylvania,FM , +449.675000,444.67500,-,141.3,,K2JZO,"Browns Mills",Burlington,New Jersey,FM , +146.610000,146.01000,-,136.5,136.5,K1WV,"Buckhannon - Buckhannon Mtn",Upshur,West Virginia,FM , +449.475000,444.47500,-,131.8,131.8,KA2PFL,"Mystic Islands",Ocean,New Jersey,FM , +146.670000,146.07000,-,131.8,131.8,W2ZQ,"West Trenton",Mercer,New Jersey,FM Fusion , +442.050000,447.05000,+,,131.8,W3MSX,"Harrison City",Westmoreland,Pennsylvania,FM EchoLink , +147.090000,147.69000,+,167.9,167.9,KB3HLL,"Williamsport - Bald Eagle Mtn",Lycoming,Pennsylvania,FM , +443.050000,448.05000,+,167.9,167.9,N3SSL,"Williamsport - Bald Eagle Mtn",Lycoming,Pennsylvania,FM DMR ,1 +444.900000,449.90000,+,173.8,173.8,KB3AWQ,"Williamsport - Bald Eagle Mtn",Lycoming,Pennsylvania,FM AllStar EchoLink , +442.425000,447.42500,+,131.8,,W3CSL,"East Monongahela",Allegheny,Pennsylvania,FM , +145.330000,144.73000,-,167.9,167.9,KB3DXU,"Williamsport - Bald Eagle Mtn",Lycoming,Pennsylvania,FM , +443.275000,448.27500,+,91.5,,KD8TC,"Stonewood",Harrison,West Virginia,FM , +146.745000,146.14500,-,131.8,CSQ,N4WFU,"Roanoke Rapids",Halifax,North Carolina,FM , +448.125000,443.12500,-,151.4,,K2PM,"Frenchtown",Hunterdon,New Jersey,FM , +147.255000,147.85500,+,162.2,162.2,W3HA,"Jim Thorpe",Carbon,Pennsylvania,FM EchoLink , +445.600000,440.60000,-,162.2,,W3HA,"Jim Thorpe",Carbon,Pennsylvania,FM EchoLink , +147.105000,147.70500,+,136.5,136.5,WD4KQI,"Bedford - Thaxton Mtn",Bedford,Virginia,FM , +146.700000,146.10000,-,192.8,192.8,N2NF,"Tuckerton",Ocean,New Jersey,FM Fusion , +440.735000,146.52000,s,D343,D343,WV8IRD,"Clarksburg",Harrison,West Virginia,FM , +147.475000,147.475000,x,CSQ,,WV8IRD,"Clarksburg",Harrison,West Virginia,FM , +147.300000,147.90000,+,151.4,151.4,W3AHS,"Williamsport - High School",Lycoming,Pennsylvania,FM AllStar EchoLink , +146.850000,146.25000,-,151.4,CSQ,WA2GWA,"Holland Township",Hunterdon,New Jersey,FM EchoLink , +449.425000,444.42500,-,103.5,103.5,W3OHX,"Freeland - Water Tower",Luzerne,Pennsylvania,FM , +147.030000,147.63000,+,77.0,77.0,W3RC,"Hazleton - Freeland Mtn",Luzerne,Pennsylvania,FM AllStar EchoLink , +146.670000,146.07000,-,103.5,103.5,W3OHX,"Hazleton - Freeland Mtn",Luzerne,Pennsylvania,FM AllStar EchoLink , +441.900000,446.90000,+,114.8,114.8,W3RC,"Hazleton - Freeland Mtn",Luzerne,Pennsylvania,FM AllStar EchoLink , +146.895000,146.29500,-,123.0,,KC8CSE,"Webster Springs - Point Mtn",Webster,West Virginia,FM , +146.685000,146.08500,-,103.5,103.5,N8FMD,"Clarksburg",Harrison,West Virginia,FM , +147.165000,147.76500,+,91.5,CSQ,WV8HC,"Clarksburg",Harrison,West Virginia,FM Fusion , +440.625000,445.62500,+,,,NC4ES,"Roanoke Rapids",Halifax,North Carolina,DMR ,1 +146.700000,146.10000,-,151.4,151.4,W3OK,"Nazareth",Northampton,Pennsylvania,FM , +444.900000,449.90000,+,151.4,151.4,W3OK,"Nazareth",Northampton,Pennsylvania,FM , +145.110000,144.51000,-,151.4,,W3OK,"Nazareth",Northampton,Pennsylvania,DSTAR , +441.700000,446.70000,+,131.8,131.8,N3KZ,"Rockton - Rockton Mtn",Clearfield,Pennsylvania,FM , +443.000000,448.00000,+,,,WR3IRS,"Rockton - Rockton Mtn",Clearfield,Pennsylvania,FM DMR ,1 +147.315000,147.91500,+,173.8,173.8,N3QC,"DuBois - Rockton Mtn",Clearfield,Pennsylvania,FM Fusion , +147.255000,147.85500,+,173.8,173.8,W3CPA,"Clearfield - Rockton Mtn",Clearfield,Pennsylvania,FM , +442.750000,447.75000,+,131.8,,KA2PFL,"Eagleswood Township",Ocean,New Jersey,FM , +145.130000,144.53000,-,103.5,,W8OO,"Crawford - Union Hill",Lewis,West Virginia,FM , +443.650000,448.65000,+,,,WR3IRS,"Lawrenceville - WNJT Tower",Mercer,New Jersey,DMR ,2 +145.270000,144.67000,-,151.4,,KB3VPK,"Easton - Braden Airport",Northampton,Pennsylvania,FM AllStar , +443.025000,448.02500,+,141.3,141.3,W4NV,"Moyock - WNOB Tower",Currituck,North Carolina,FM Fusion , +146.655000,146.05500,-,136.5,,N3LWY,"Easton - Morgan Hill",Northampton,Pennsylvania,FM , +147.225000,147.82500,+,131.8,,KA3BFI,"East Monongahela",Allegheny,Pennsylvania,FM EchoLink , +443.350000,448.35000,+,131.8,131.8,W3CDU,"East Monongahela",Allegheny,Pennsylvania,FM , +147.270000,147.87000,+,131.8,CSQ,WB3CCN,"East Monongahela",Allegheny,Pennsylvania,FM , +147.315000,147.91500,+,136.5,,W3ATE,"Hillsboro - Droop Mtn",Pocahontas,West Virginia,FM EchoLink , +145.330000,144.73000,-,136.5,,W3ATE,"Hillsboro - Droop Mtn",Pocahontas,West Virginia,FM , +441.300000,446.30000,+,,,WR3IRS,"Fairmount Twp - Red Rock",Luzerne,Pennsylvania,DMR ,1 +448.575000,443.57500,-,141.3,,WA2NEW,"Beach Haven",Ocean,New Jersey,FM , +147.060000,147.66000,+,103.5,,W8OO,"Crawford - Union Hill",Lewis,West Virginia,FM , +442.650000,447.65000,+,131.8,131.8,W2ZQ,"Lawrenceville",Mercer,New Jersey,FM Fusion WIRES-X , +447.925000,442.92500,-,D205,D205,W2MCC,"Phillipsburg - St Luke's Hospital",Warren,New Jersey,FM , +146.460000,147.46000,s,131.8,,N2RE,"Lawrenceville - WNJT Tower",Mercer,New Jersey,FM , +147.120000,147.72000,+,131.8,,W3OC,"Lincoln",Allegheny,Pennsylvania,FM , +442.250000,447.25000,+,131.8,,W3OC,"Lincoln",Allegheny,Pennsylvania,FM EchoLink , +147.315000,147.91500,+,131.8,131.8,K3PSP,"Waynesburg",Greene,Pennsylvania,FM EchoLink , +444.500000,449.50000,+,100.0,100.0,N3FCK,"Shickshinny",Luzerne,Pennsylvania,FM , +147.390000,147.99000,+,173.8,,KE3DR,"Rockton",Clearfield,Pennsylvania,FM AllStar , +147.165000,147.76500,+,,,WR3IRS,"Rockton - Rockton Mtn",Clearfield,Pennsylvania,DMR ,1 +443.475000,448.47500,+,173.8,,N5NWC,"Punxsutawney",Jefferson,Pennsylvania,FM , +147.105000,147.70500,+,123.0,123.0,W2MER,"West Windsor",Mercer,New Jersey,FM Fusion , +449.575000,444.57500,-,151.4,,N3MSK,"Bloomsbury",Hunterdon,New Jersey,FM , +444.900000,449.90000,+,131.8,,N1RS,"Apollo",Armstrong,Pennsylvania,FM , +444.925000,449.92500,+,131.8,,N1RS,"Apollo",Armstrong,Pennsylvania,FM , +146.970000,146.37000,-,131.8,,N1RS,"Apollo",Armstrong,Pennsylvania,FM , +145.350000,144.75000,-,167.9,167.9,KB3DXU,"Waterville - Ramsey",Lycoming,Pennsylvania,FM , +443.575000,448.57500,+,,,N4HRS,"South Boston",Halifax,Virginia,DMR ,9 +147.390000,147.99000,+,100.0,,KC8CSE,"Hillsboro - Briery Knob",Pocahontas,West Virginia,FM EchoLink , +445.425000,440.42500,-,,,K2HR,"Manahawkin",Ocean,New Jersey,DMR ,3 +147.060000,146.46000,-,82.5,,KF4AGO,"South Boston",Halifax,Virginia,FM , +146.835000,146.23500,-,127.3,,WU2E,"Manahawkin",Ocean,New Jersey,FM , +448.075000,443.07500,-,,,WA3BXW,"Manahawkin",Ocean,New Jersey,DMR ,1 +445.075000,440.07500,-,141.3,141.3,W2NJR,"Manahawkin",Ocean,New Jersey,FM , +443.975000,448.97500,+,123.0,,N8MIN,"Weston",Lewis,West Virginia,FM , +444.300000,449.30000,+,131.8,,N1RS,"Vandergrift",Westmoreland,Pennsylvania,FM , +147.285000,147.88500,+,131.8,131.8,K3PSP,"Scenery Hill",Washington,Pennsylvania,FM EchoLink , +146.640000,146.04000,-,131.8,131.8,K3MJW,"New Kensington",Westmoreland,Pennsylvania,FM EchoLink , +444.525000,449.52500,+,131.8,,K3MJW,"New Kensington",Westmoreland,Pennsylvania,FM Fusion , +145.350000,144.75000,-,100.0,100.0,NM4V,"South Boston",Halifax,Virginia,FM EchoLink Fusion WIRES-X , +444.000000,449.00000,+,131.8,131.8,WU3U,"Monroeville",Allegheny,Pennsylvania,FM DMR ,7 +443.925000,448.92500,+,100.0,100.0,NM4V,"South Boston",Halifax,Virginia,FM Fusion , +444.625000,449.62500,+,100.0,100.0,NM4V,"South Boston",Halifax,Virginia,FM Fusion , +147.375000,147.97500,+,151.4,CSQ,WB2NQV,"Cherryville",Hunterdon,New Jersey,FM , +147.360000,147.96000,+,131.8,CSQ,N3GRQ,"Saylorsburg",Monroe,Pennsylvania,FM P-25 ,293 +444.850000,449.85000,+,141.3,,W2CRA,"Cherryville",Hunterdon,New Jersey,FM , +444.500000,449.50000,+,131.8,,KA3IDK,"West Mifflin",Allegheny,Pennsylvania,FM , +444.525000,449.52500,+,,,KA3IDK,"West Mifflin",Allegheny,Pennsylvania,FM , +444.550000,449.55000,+,131.8,,KA3IDK,"West Mifflin",Allegheny,Pennsylvania,FM , +446.725000,441.72500,-,,,N2MRH,"Barnegat",Ocean,New Jersey,DMR ,1 +442.800000,447.80000,+,123.0,,KD2ARB,"Belle Mead",Somerset,New Jersey,AllStar DMR , +146.445000,147.44500,s,131.8,,KC2GUM,"Lacey - Bamber Lakes Fire Co",Ocean,New Jersey,FM , +449.875000,444.87500,-,127.3,127.3,KC2IRV,"Wind Gap",Northampton,Pennsylvania,FM AllStar EchoLink , +145.450000,144.85000,-,167.9,167.9,KB3DXU,"Huntersville - Long Ridge",Lycoming,Pennsylvania,FM , +145.430000,144.83000,-,79.7,,N3KZ,"Waterford Works",Camden,New Jersey,FM , +147.445000,146.44500,s,192.8,,N2JBC,"Franklin Lakes",Bergen,New Jersey,FM , +145.450000,144.85000,-,131.8,,K2NI,"Ellisdale",Monmouth,New Jersey,FM , +147.240000,147.84000,+,131.8,,N2RDM,"Cream Ridge",Monmouth,New Jersey,FM , +147.390000,147.99000,+,,,NJ2DG,"Martinsville",Somerset,New Jersey,DSTAR , +446.225000,441.22500,-,131.8,,N3TXG,"Saylorsburg",Monroe,Pennsylvania,FM , +448.425000,443.42500,-,,,KC2IRV,"Effort - Pimple Hill",Monroe,Pennsylvania,DMR ,1 +146.445000,144.65000,s,127.3,127.3,KC2IRV,"Effort",Monroe,Pennsylvania,FM AllStar , +145.130000,144.53000,-,131.8,131.8,WB4YNF,"Ahoskie",Hertford,North Carolina,FM , +444.200000,449.20000,+,131.8,,WB4YNF,"Ahoskie",Hertford,North Carolina,FM , +444.337500,449.33750,+,,,WB4YNF,"Ahoskie",Hertford,North Carolina,DMR ,1 +446.575000,441.57500,-,151.4,,KG3I,"Jonas",Monroe,Pennsylvania,FM , +146.805000,146.20500,-,82.5,,N3CSE,"Hunlock Creek",Luzerne,Pennsylvania,FM , +439.125000,444.12500,+,114.8,,N2ACF,"Barnegat",Ocean,New Jersey,FM , +442.525000,447.52500,+,173.8,,K3JRW,"DuBois",Clearfield,Pennsylvania,FM , +444.475000,449.47500,+,,,N4HRS,"Roanoke - Tinker Mtn",Roanoke,Virginia,DMR ,9 +445.375000,440.37500,-,91.5,91.5,K4MTP,"Albrightsville - Pohopoco Mtn",Monroe,Pennsylvania,FM AllStar , +146.730000,146.13000,-,94.8,94.8,KB3CNN,"Homestead",Allegheny,Pennsylvania,FM , +444.100000,449.10000,+,71.9,71.9,KB3CNN,"Pittsburgh",Allegheny,Pennsylvania,FM , +146.910000,146.31000,-,131.8,,KG4GEJ,"Ahoskie",Hertford,North Carolina,FM , +145.390000,144.79000,-,103.5,,N8MIN,"Weston - Sugar Loaf",Lewis,West Virginia,FM , +449.325000,444.32500,-,107.2,107.2,N2BEI,"Hillsborough - Sourland Mtn",Somerset,New Jersey,FM P-25 , +442.100000,447.10000,+,131.8,131.8,N3KZ,"Lake Harmony - Big Boulder Ski Area",Carbon,Pennsylvania,FM , +146.865000,146.26500,-,173.8,,KB3FPN,"Reynoldsville",Jefferson,Pennsylvania,FM , +146.820000,146.22000,-,110.9,110.9,W2SJT,"Washington - Montana Mtn",Warren,New Jersey,FM EchoLink , +443.350000,448.35000,+,141.3,,W2DOR,"Lakehurst",Ocean,New Jersey,FM EchoLink , +448.275000,443.27500,-,131.8,131.8,W3IIY,"Long Pond - Pimple Hill",Monroe,Pennsylvania,FM , +447.275000,442.27500,-,151.4,,KG3I,"Long Pond - Pimple Hill",Monroe,Pennsylvania,FM , +447.225000,442.22500,-,131.8,131.8,N3TXG,"Bangor",Northampton,Pennsylvania,FM , +445.218750,440.21875,-,,,N2DCE,"Bangor",Northampton,Pennsylvania,DMR ,1 +448.625000,443.62500,-,173.8,,W3NTT,"Long Pond",Monroe,Pennsylvania,FM AllStar EchoLink , +145.450000,144.85000,-,131.8,131.8,WB4YNF,"Aulander",Hertford,North Carolina,FM , +443.612500,448.61250,+,,,K2NYX,"Jackson",Ocean,New Jersey,DMR ,6 +441.800000,446.80000,+,131.8,131.8,N3KZ,"Benton - Red Rock Mtn",Luzerne,Pennsylvania,FM , +147.000000,147.60000,+,77.0,77.0,N3VTH,"Benton - Red Rock",Luzerne,Pennsylvania,FM , +145.370000,144.77000,-,131.8,131.8,WA3WOM,"Tarentum",Allegheny,Pennsylvania,FM , +442.750000,447.75000,+,,,W3PRL,"New Kensington",Westmoreland,Pennsylvania,FM , +146.490000,147.49000,s,131.8,,N1RS,"New Kensington",Westmoreland,Pennsylvania,FM , +145.470000,144.87000,-,71.9,71.9,KB3CNN,"Hazelwood",Allegheny,Pennsylvania,FM , +145.330000,144.73000,-,131.8,131.8,AB3PJ,"Brentwood - Fire Dept",Allegheny,Pennsylvania,FM , +444.050000,449.05000,+,131.8,,KA3IDK,"Hazelwood",Allegheny,Pennsylvania,FM , +147.015000,147.61500,+,D411,D411,WB2NQV,"Glen Gardner - Mt Kipp",Hunterdon,New Jersey,FM Fusion , +446.475000,441.47500,-,141.3,,W2CRA,"Glen Gardner - Mt Kipp",Hunterdon,New Jersey,FM , +145.525000,145.525000,x,97.4,,AC3OC,"Sweet Valley",Luzerne,Pennsylvania,FM , +441.150000,446.15000,+,,,KA2DMR,"Forked River",Ocean,New Jersey,DMR ,1 +146.835000,146.23500,-,110.9,,KC8ECX,"Cowen",Webster,West Virginia,FM , +448.475000,443.47500,-,74.4,74.4,N2IXU,"Bayville",Ocean,New Jersey,FM , +145.190000,144.59000,-,131.8,,W3VC,"Pittsburgh - CMU",Allegheny,Pennsylvania,FM , +146.610000,146.01000,-,131.8,131.8,W3PGH,"Carrick",Allegheny,Pennsylvania,FM , +444.950000,449.95000,+,88.5,88.5,W3PGH,"Carrick",Allegheny,Pennsylvania,FM , +146.460000,147.46000,s,100.0,100.0,N3FCK,"Wilkes-Barre - Laurel Run",Luzerne,Pennsylvania,FM , +444.650000,449.65000,+,131.8,131.8,W3VC,"Pittsburgh - Hamerschlag Hall (CMU)",Allegheny,Pennsylvania,FM P-25 , +443.850000,448.85000,+,110.9,,W2SJT,"Washington",Warren,New Jersey,FM , +446.425000,441.42500,-,162.2,,K2FN,"Washington",Warren,New Jersey,FM , +446.725000,441.72500,-,131.8,,N3GRQ,"Saylorsburg",Monroe,Pennsylvania,FM P-25 ,293 +440.600000,445.60000,+,131.8,131.8,K3CSF,"Castle Shannon",Allegheny,Pennsylvania,FM EchoLink , +146.955000,146.35500,-,103.5,103.5,K8DCA,"West Union",Doddridge,West Virginia,FM , +147.150000,147.75000,+,74.4,74.4,W3WAN,"Wilkes-Barre",Luzerne,Pennsylvania,FM AllStar , +443.450000,448.45000,+,100.0,100.0,W3YJ,"Pittsburgh - U of P",Allegheny,Pennsylvania,FM , +441.950000,446.95000,+,131.8,131.8,WB4YNF,"Aulander - St John Rd Tower",Hertford,North Carolina,FM Fusion , +147.135000,147.73500,+,151.4,151.4,K2NJ,"Hillsborough",Somerset,New Jersey,FM P-25 ,293 +443.400000,448.40000,+,141.3,141.3,N2RE,"South Brunswick",Middlesex,New Jersey,FM , +145.150000,144.55000,-,167.9,167.9,KB3DXU,"Trout Run - Shrivers Ridge",Lycoming,Pennsylvania,FM , +444.912500,449.91250,+,141.3,141.3,KB2EAR,"Kendall Park",Middlesex,New Jersey,FM AllStar EchoLink , +146.880000,146.28000,-,88.5,88.5,W3EXW,"Pittsburgh - WQED TV-13 Tower",Allegheny,Pennsylvania,FM , +146.820000,146.22000,-,,,W3EXW,"Pittsburgh - WQED Tower",Allegheny,Pennsylvania,DSTAR , +441.825000,446.82500,+,107.2,,W4FYB,"Chatham",Pittsylvania,Virginia,FM , +444.450000,449.45000,+,100.0,,W8TFC,"Richwood",Nicholas,West Virginia,FM , +145.190000,144.59000,-,146.2,,WB8YJJ,"Richwood",Nicholas,West Virginia,FM , +147.150000,147.75000,+,100.0,,KB8YDG,"Richwood",Nicholas,West Virginia,FM , +443.375000,448.37500,+,100.0,,KC8SDN,"Richwood",Nicholas,West Virginia,FM , +147.015000,147.61500,+,,100.0,KC8SDN,"Richwood - Grasshopper Knob",Nicholas,West Virginia,FM , +444.000000,449.00000,+,107.2,,KF4YLM,"Paint Bank - Potts Mtn",Craig,Virginia,DMR ,9 +449.825000,444.82500,-,131.8,,WA2RES,"Toms River",Ocean,New Jersey,FM , +442.350000,447.35000,+,,,N3RZL,"Pennfield - Boone Mtn",Clearfield,Pennsylvania,DMR ,1 +447.518750,442.51875,-,,,AC2DW,"Toms River",Ocean,New Jersey,DMR ,2 +444.000000,449.00000,+,141.3,,WA2OTP,"Toms River",Ocean,New Jersey,FM , +448.625000,443.62500,-,141.3,141.3,NJ2AR,"Toms River",Ocean,New Jersey,FM Fusion , +146.655000,146.05500,-,127.3,141.3,W2NJR,"Toms River - Holiday City",Ocean,New Jersey,FM DMR EchoLink ,1 +145.490000,144.89000,-,131.8,131.8,K3PSP,"Washington - Mt Wheeler",Washington,Pennsylvania,FM Fusion WIRES-X , +147.180000,147.78000,+,173.8,,N3SNN,"Driftwood - Grove Hill",Cameron,Pennsylvania,FM EchoLink , +443.975000,448.97500,+,131.8,131.8,K3QY,"Cadogan",Armstrong,Pennsylvania,FM AllStar EchoLink , +442.750000,447.75000,+,107.2,,W4KZK,"Roanoke - Mill Mtn",Roanoke,Virginia,FM , +146.790000,146.19000,-,CSQ,CSQ,K3PSP,"Washington - Washington Park",Washington,Pennsylvania,FM EchoLink , +446.875000,441.87500,-,141.3,141.3,WA2JWR,"Toms River",Ocean,New Jersey,FM DMR ,3 +145.410000,144.81000,-,100.0,,N3DAX,"Wilkes-Barre",Luzerne,Pennsylvania,FM , +146.610000,146.01000,-,82.5,,WB3FKQ,"Wilkes-Barre",Luzerne,Pennsylvania,FM , +442.200000,447.20000,+,131.8,131.8,N3KZ,"Wilkes-Barre - Plains Township",Luzerne,Pennsylvania,FM , +441.750000,446.75000,+,,,WR3IRS,"Wilkes-Barre",Luzerne,Pennsylvania,DMR ,1 +146.955000,146.35500,-,131.8,131.8,N3SH,"Mount Lebanon - St Clair Mem Hospital",Allegheny,Pennsylvania,FM , +443.650000,448.65000,+,131.8,131.8,N3FB,"Canonsburg",Washington,Pennsylvania,FM , +443.700000,448.70000,+,,,KC2IRV,"Tannersville - Camelback Mountain",Monroe,Pennsylvania,DMR ,1 +442.500000,447.50000,+,131.8,131.8,N3KZ,"Tannersville - Camelback Mtn",Monroe,Pennsylvania,FM , +145.310000,144.71000,-,85.4,85.4,N3XXH,"Laporte",Sullivan,Pennsylvania,FM , +442.500000,447.50000,+,131.8,131.8,KS3R,"Bridgeville",Allegheny,Pennsylvania,FM , +444.450000,449.45000,+,103.5,103.5,W3KWH,"Pittsburgh - Mt Washington",Allegheny,Pennsylvania,FM Fusion WIRES-X , +145.130000,144.53000,-,131.8,131.8,KS3R,"Bridgeville",Allegheny,Pennsylvania,FM , +147.090000,147.69000,+,88.5,88.5,W3EXW,"Fineview - WPXI Tower",Allegheny,Pennsylvania,FM EchoLink , +146.940000,146.34000,-,100.0,,KE8HPE,"Fenwick - Fenwick Mtn",Nicholas,West Virginia,FM EchoLink Fusion , +441.550000,446.55000,+,,,WR3IRS,"Tannersville - Camelback Mtn",Monroe,Pennsylvania,DMR ,1 +444.300000,449.30000,+,186.2,,WA3HLC,"Ulysses - Bailey Hill",Potter,Pennsylvania,FM , +146.910000,146.31000,-,127.3,127.3,W2DOR,"Toms River - The Bennett Bubble",Ocean,New Jersey,FM , +145.555000,146.15500,+,91.5,91.5,K3ODX,"Stroudsburg - Totts Gap",Monroe,Pennsylvania,FM , +145.230000,144.63000,-,77.0,,W3WAN,"Tannersville",Monroe,Pennsylvania,FM AllStar , +146.865000,146.26500,-,100.0,,WX3OES,"Tannersville",Monroe,Pennsylvania,FM AllStar , +145.450000,144.85000,-,82.5,82.5,K3YTL,"Wilkes-Barre - Bunker Hill",Luzerne,Pennsylvania,FM , +147.030000,147.63000,+,123.0,,W3KWH,"Carnegie",Allegheny,Pennsylvania,FM , +146.655000,146.05500,-,131.8,131.8,WA4VTX,"Elizabeth City",Pasquotank,North Carolina,FM , +442.550000,447.55000,+,131.8,131.8,N3SH,"Pittsburgh - WPGH Tower",Allegheny,Pennsylvania,FM , +449.375000,444.37500,-,123.0,,NE2E,"Lakewood",Ocean,New Jersey,FM , +444.400000,449.40000,+,107.2,107.2,KF4YLM,"New Castle - Sinking Creek Mtn",Craig,Virginia,FM NXDN P-25 Fusion ,293 +444.400000,449.40000,+,88.5,88.5,W3EXW,"North Hills - WPXI TV-11",Allegheny,Pennsylvania,FM , +146.700000,146.10000,-,107.2,,KO4TDR,"Danville - White Oak Mtn",Pittsylvania,Virginia,FM , +444.725000,449.72500,+,,,KO4TDR,"Danville - White Oak Mtn",Pittsylvania,Virginia,DMR ,10 +145.310000,144.71000,-,100.0,,KB2RQE,"Fort Lee",Bergen,New Jersey,FM , +448.375000,443.37500,-,91.5,,K3ODX,"Stroudsburg - Totts Gap",Monroe,Pennsylvania,FM , +446.500000,441.50000,-,97.4,97.4,KB3TEM,"Pittston",Luzerne,Pennsylvania,FM AllStar EchoLink WIRES-X , +146.940000,146.34000,-,107.2,107.2,W4KDN,"Roanoke - Long Ridge",Roanoke,Virginia,FM , +444.850000,449.85000,+,107.2,,W4KZK,"Salem - Sugar Loaf Mtn",Roanoke,Virginia,FM , +440.750000,445.75000,+,,,N2DML,"Somerset",Somerset,New Jersey,DMR ,9 +443.600000,448.60000,+,100.0,100.0,N3FCK,"Pittston - Suscon Mtn",Luzerne,Pennsylvania,FM , +448.175000,443.17500,-,,,W2SOM,"Bridgewater",Somerset,New Jersey,DMR ,1 +440.700000,445.70000,+,,,KD4EG,"Roanoke - Long Ridge",Roanoke,Virginia,DMR ,1 +146.505000,147.50500,s,131.8,,N1RS,"Cowansville",Armstrong,Pennsylvania,FM , +444.300000,449.30000,+,131.8,,N1RS,"Cowansville",Armstrong,Pennsylvania,FM , +444.375000,449.37500,+,100.0,100.0,K4JDR,"Henderson",Vance,North Carolina,FM AllStar EchoLink IRLP , +440.100000,445.10000,+,,,WR3IRS,"Forkston",Wyoming,Pennsylvania,DMR ,1 +446.175000,441.17500,-,114.8,114.8,KA2CAF,"Arrowhead Village",Ocean,New Jersey,FM Fusion , +440.300000,445.30000,+,,,KB2RF,"Howell",Monmouth,New Jersey,DMR ,1 +146.490000,147.49000,s,141.3,,K2RFI,"Brick Township",Ocean,New Jersey,FM EchoLink IRLP , +146.475000,147.47500,s,110.9,,WB2NMI,"Columbia - Hainesburg",Warren,New Jersey,FM , +145.290000,144.69000,-,131.8,131.8,K3PSG,"Cabot - Winfield Twp Community Park",Butler,Pennsylvania,FM AllStar , +146.880000,146.28000,-,107.2,107.2,KF4RGH,"Salem - 12 O'Clock Knob",Roanoke,Virginia,FM , +442.250000,447.25000,+,141.3,141.3,W2QW,"East Brunswick",Middlesex,New Jersey,FM , +146.835000,146.23500,-,131.8,131.8,KX4NC,"Hertford",Perquimans,North Carolina,FM , +146.910000,146.31000,-,123.0,123.0,KC8FZH,"Cameron - Cameron Ridge",Marshall,West Virginia,FM Fusion , +445.725000,440.72500,-,136.5,,N3MSK,"Martinsville",Somerset,New Jersey,FM , +146.490000,147.49000,s,141.3,,W2NJR,"Brick Township",Ocean,New Jersey,FM , +444.075000,449.07500,+,203.5,203.5,NC4ES,"Scotland Neck - Brown Tower",Halifax,North Carolina,FM , +147.030000,147.63000,+,141.3,,N2GS,"Long Valley",Morris,New Jersey,FM , +441.650000,446.65000,+,,,NJ2DG,"Martinsville",Somerset,New Jersey,FM , +447.075000,442.07500,-,,,K1DO,"Martinsville",Somerset,New Jersey,DMR ,1 +147.285000,147.88500,+,141.3,141.3,W2NJR,"Martinsville",Somerset,New Jersey,FM , +145.140000,144.54000,-,,,NJ2DG,"Martinsville",Somerset,New Jersey,DSTAR , +145.170000,144.57000,-,100.0,CSQ,W4BAD,"Oxford",Granville,North Carolina,FM AllStar EchoLink , +444.600000,449.60000,+,,,W4BAD,"Oxford",Granville,North Carolina,DMR ,1 +440.800000,445.80000,+,141.3,141.3,K2MID,"Sayreville",Middlesex,New Jersey,FM , +449.275000,444.27500,-,151.4,151.4,KC2CWP,"South Brunswick",Middlesex,New Jersey,FM , +147.390000,147.99000,+,131.8,131.8,K3PSP,"McDonald",Washington,Pennsylvania,FM EchoLink , +444.300000,449.30000,+,,,AA4RV,"Epsom",Franklin,North Carolina,DSTAR , +147.030000,147.63000,+,88.5,88.5,AA4RV,"Epsom",Franklin,North Carolina,FM , +145.410000,144.81000,-,173.8,173.8,K3QY,"Widnoon",Armstrong,Pennsylvania,FM AllStar EchoLink , +444.212500,449.21250,+,,,N4HRS,"Roanoke - Poor Mtn",Roanoke,Virginia,FM DMR ,9 +147.165000,147.76500,+,,,WB4EOT,"Salem - Ft Lewis Mtn",Roanoke,Virginia,DMR ,1 +147.225000,147.82500,+,100.0,100.0,KF4YLM,"Lewisburg - Muddy Creek Mtn",Greenbrier,West Virginia,FM EchoLink , +443.550000,448.55000,+,141.3,141.3,WB2SNN,"South River",Middlesex,New Jersey,FM AllStar , +145.110000,144.51000,-,127.3,127.3,N2MO,"Allenwood",Monmouth,New Jersey,FM Fusion WIRES-X , +448.075000,443.07500,-,141.3,141.3,WW2BSA,"Hackettstown - Strand Theater",Warren,New Jersey,FM Fusion , +441.400000,446.40000,+,D054,D054,NJ2DG,"Martinsville",Somerset,New Jersey,FM Fusion , +145.080000,146.48000,s,,,WB4EOT,"Rocky Mount - Thornton Mtn",Franklin,Virginia,DMR ,1 +145.290000,144.69000,-,91.5,91.5,WB8WV,"Glenville",Gilmer,West Virginia,FM , +147.240000,147.84000,+,123.0,,AB8WB,"Gassaway",Braxton,West Virginia,FM , +443.750000,448.75000,+,77.0,77.0,W4KZK,"Salem - 12 O'Clock Knob",Roanoke,Virginia,FM AllStar , +146.805000,146.20500,-,173.8,,KC3LRG,"Emporium",Cameron,Pennsylvania,FM , +442.200000,447.20000,+,,,N3RZL,"Ridgway - Bootjack Mtn.",Elk,Pennsylvania,DMR ,1 +145.270000,144.67000,-,103.5,103.5,N8FMD,"Birch River",Nicholas,West Virginia,FM , +444.325000,449.32500,+,,,KA8ZXP,"Glenville",Gilmer,West Virginia,FM , +442.925000,447.92500,+,107.2,107.2,W4KZK,"Bent Mountain - Slings Gap",Roanoke,Virginia,FM , +444.400000,449.40000,+,141.3,,WB2HKK,"Old Bridge",Middlesex,New Jersey,FM AllStar , +145.250000,144.65000,-,131.8,131.8,K3PSP,"West Alexander",Washington,Pennsylvania,FM EchoLink , +446.175000,441.17500,-,114.8,114.8,W2CJA,"Parlin",Middlesex,New Jersey,FM Fusion , +147.120000,147.72000,+,162.2,,W2CJA,"Parlin",Middlesex,New Jersey,FM Fusion , +446.475000,441.47500,-,114.8,114.8,N3FYI,"Blossburg",Tioga,Pennsylvania,FM AllStar EchoLink , +440.287500,445.28750,+,,,WR3IRS,"Warren",Somerset,New Jersey,DMR ,1 +444.150000,449.15000,+,131.8,,KA3IRT,"Coraopolis",Allegheny,Pennsylvania,FM EchoLink , +146.625000,146.02500,-,141.3,141.3,W2QW,"Warren",Somerset,New Jersey,FM AllStar EchoLink , +441.887500,446.88750,+,,,K4ITL,"Roanoke - Poor Mtn",Roanoke,Virginia,DMR ,1 +147.000000,147.60000,+,173.8,173.8,N3NIA,"Ridgway - Boot Jack Mtn",Elk,Pennsylvania,FM Fusion , +444.350000,449.35000,+,141.3,141.3,W2NJR,"Wall Twp",Monmouth,New Jersey,FM , +145.390000,144.79000,-,107.2,107.2,N4MGQ,"Roanoke - Poor Mtn",Roanoke,Virginia,FM AllStar , +145.410000,144.81000,-,103.5,,N4VL,"Roanoke - Poor Mtn",Roanoke,Virginia,FM , +146.760000,146.16000,-,156.7,156.7,K2GE,"Sayreville",Middlesex,New Jersey,FM EchoLink IRLP , +443.200000,448.20000,+,141.3,141.3,K2GE,"Sayreville",Middlesex,New Jersey,FM EchoLink IRLP , +444.775000,449.77500,+,,,W5CUI,"Roanoke - Poor Mtn",Roanoke,Virginia,DMR ,1 +442.700000,447.70000,+,167.9,CSQ,W7CP,"Roanoke - Poor Mtn",Roanoke,Virginia,FM , +146.985000,146.38500,-,107.2,107.2,W4CA,"Roanoke - Poor Mtn",Roanoke,Virginia,FM , +442.500000,447.50000,+,107.2,,W4CA,"Roanoke - Poor Mtn",Roanoke,Virginia,FM P-25 Fusion , +442.200000,447.20000,+,107.2,107.2,AE4JA,"Roanoke - Poor Mtn",Roanoke,Virginia,FM Fusion WIRES-X , +146.775000,146.17500,-,141.3,141.3,W2NJR,"Wall Twp",Monmouth,New Jersey,FM EchoLink , +441.675000,446.67500,+,,,W4BAD,"Roxboro",Person,North Carolina,DMR ,1 +147.330000,147.93000,+,131.8,131.8,WA4VTX,"Hertford",Perquimans,North Carolina,FM , +442.162500,447.16250,+,,,WB4YNF,"Hertford",Perquimans,North Carolina,DMR ,1 +146.745000,146.14500,-,107.2,107.2,K1GG,"Roanoke - Poor Mtn",Roanoke,Virginia,FM EchoLink , +444.875000,449.87500,+,123.0,123.0,KC8FZH,"Saint Joseph",Marshall,West Virginia,FM Fusion , +445.275000,440.27500,-,141.3,141.3,W2LPC,"South Plainfield - Spring Lake Park",Middlesex,New Jersey,FM AllStar DMR EchoLink ,1 +147.285000,147.88500,+,173.8,,N3NWL,"Ridgway",Elk,Pennsylvania,FM , +443.800000,448.80000,+,173.8,,N3NIA,"Ridgway - Boot Jack Mtn",Elk,Pennsylvania,FM , +146.805000,146.20500,-,94.8,,WR2M,"Budd Lake",Morris,New Jersey,FM , +444.175000,449.17500,+,D712,D712,N4HRS,"Roanoke - Poor Mtn",Roanoke,Virginia,FM , +147.105000,147.70500,+,173.8,,N3JGT,"Sigel",Jefferson,Pennsylvania,FM AllStar , +443.275000,448.27500,+,110.9,,N3GPM,"Sigel",Jefferson,Pennsylvania,FM , +146.625000,146.02500,-,107.2,107.2,KO4TDR,"Danville - Eskey Realty Building",Pittsylvania,Virginia,FM , +448.925000,443.92500,-,,,K2DMR,"Mt Olive, Twp",Morris,New Jersey,DMR NXDN ,1 +146.835000,146.23500,-,131.8,131.8,WB4YNF,"Hertford",Perquimans,North Carolina,FM , +146.940000,146.34000,-,156.7,156.7,K2ETS,"Watchung",Somerset,New Jersey,FM , +440.250000,445.25000,+,,,WB2FYF,"South Amboy",Middlesex,New Jersey,DMR ,1 +147.195000,147.79500,+,127.3,127.3,NR3K,"Leetonia - Cedar Mtn",Tioga,Pennsylvania,FM , +145.210000,144.61000,-,127.3,127.3,NR3K,"Wellsboro - Cedar Mtn",Tioga,Pennsylvania,FM , +443.650000,448.65000,+,127.3,127.3,NR3K,"Wellsboro - Cedar Mtn",Tioga,Pennsylvania,FM , +442.000000,447.00000,+,131.8,131.8,N3KZ,"Forkston - Forkston Mtn",Wyoming,Pennsylvania,FM , +146.655000,146.05500,-,123.0,,KF8LO,"Flatwoods",Braxton,West Virginia,FM , +146.805000,146.20500,-,118.8,118.8,AA4RV,"Louisburg",Franklin,North Carolina,FM , +443.900000,448.90000,+,CSQ,131.8,K3PSG,"Butler - EOC",Butler,Pennsylvania,FM AllStar Fusion , +442.150000,447.15000,+,141.3,,KB2MMR,"Avon",Monmouth,New Jersey,FM , +146.940000,146.34000,-,127.3,127.3,K3CSG,"Scranton - Pinnacle Rock",Lackawanna,Pennsylvania,FM Fusion , +146.715000,146.11500,-,136.5,136.5,N3MBK,"Scranton - Bald Mtn",Lackawanna,Pennsylvania,FM , +445.875000,440.87500,-,82.5,,W3USR,"Scranton - The University of Scranton",Lackawanna,Pennsylvania,FM , +146.985000,146.38500,-,131.8,131.8,WS2R,"Roxbury - Mooney Mtn Meadows",Morris,New Jersey,FM EchoLink , +147.285000,147.88500,+,127.3,127.3,WB3FEQ,"Scranton",Lackawanna,Pennsylvania,FM , +442.300000,447.30000,+,186.2,,K3PSG,"Butler - Butler Township",Butler,Pennsylvania,FM , +441.350000,446.35000,+,,,N3MBK,"Scranton",Lackawanna,Pennsylvania,DMR ,2 +146.760000,146.16000,-,162.2,,KC8CSE,"Union - Bickett's Knob",Monroe,West Virginia,FM EchoLink , +448.925000,443.92500,-,141.3,141.3,K2EPD,"Tinton Falls - Garden State Pkway Exit 105",Monmouth,New Jersey,FM Fusion , +444.000000,449.00000,+,114.8,,N2ACF,"Tinton Falls",Monmouth,New Jersey,FM , +447.775000,442.77500,-,136.5,136.5,N2XP,"Succasunna",Morris,New Jersey,FM , +442.675000,447.67500,+,107.2,107.2,WB4EOT,"Rocky Mount",Franklin,Virginia,FM AllStar , +146.775000,146.17500,-,136.5,136.5,WB3KGD,"Scranton - I-81/I-380/I-84",Lackawanna,Pennsylvania,FM Fusion , +441.700000,446.70000,+,131.8,131.8,K3UKE,"Ambridge",Beaver,Pennsylvania,FM AllStar , +447.780000,442.78000,-,136.5,,WT2S,"Succasunna",Morris,New Jersey,FM , +442.875000,447.87500,+,,,WV8CH,"Alderson - Keeney Mtn",Summers,West Virginia,DMR ,1 +145.470000,144.87000,-,100.0,,WV8T,"Summersville - Lonetree Mtn",Nicholas,West Virginia,FM , +146.655000,146.05500,-,146.2,,WB3KGD,"Dunmore",Lackawanna,Pennsylvania,FM , +147.045000,147.64500,+,67.0,67.0,W2GSA,"Asbury Park",Monmouth,New Jersey,FM EchoLink Fusion , +444.325000,449.32500,+,110.9,,N3HZX,"Clarion",Clarion,Pennsylvania,FM , +147.300000,147.90000,+,131.8,,K3PSG,"Butler - Alameda Park",Butler,Pennsylvania,FM AllStar , +147.255000,147.85500,+,141.3,141.3,W2LI,"Murray Hill",Union,New Jersey,FM , +449.975000,444.97500,-,141.3,141.3,W2LI,"Murray Hill",Union,New Jersey,FM EchoLink IRLP , +147.210000,147.81000,+,77.0,77.0,N3KZ,"Forkston - Forkston Mtn",Wyoming,Pennsylvania,FM , +441.150000,446.15000,+,100.0,100.0,N3FCK,"Forkston",Wyoming,Pennsylvania,FM , +444.950000,449.95000,+,131.8,,K2WMA,"Jefferson",Morris,New Jersey,FM EchoLink , +444.575000,449.57500,+,156.7,,W8MSD,"Wheeling - Mt Olivet",Ohio,West Virginia,FM EchoLink , +146.715000,146.11500,-,206.5,,N2DAE,"Randolph",Morris,New Jersey,FM , +147.360000,147.96000,+,110.9,,WV8TC,"Middlebourne",Tyler,West Virginia,FM , +441.500000,446.50000,+,141.3,,W2GCM,"Randolph",Morris,New Jersey,FM AllStar EchoLink , +145.485000,144.88500,-,151.4,,AA2OW,"Middletown",Monmouth,New Jersey,FM , +448.725000,443.72500,-,151.4,,N2DR,"Middletown",Monmouth,New Jersey,FM , +146.985000,146.38500,-,CSQ,,KF8LL,"New Martinsville",Wetzel,West Virginia,FM , +147.360000,147.96000,+,123.0,123.0,KC8FZH,"Saint Joseph",Marshall,West Virginia,FM Fusion , +443.250000,448.25000,+,141.3,,WS2Q,"Morris Township",Morris,New Jersey,FM , +146.715000,146.11500,-,110.9,110.9,KC8FZH,"Moundsville - Grand Vue State Park",Marshall,West Virginia,FM Fusion WIRES-X , +441.950000,446.95000,+,123.0,123.0,KC8FZH,"Moundsville - Grand Vue State Park",Marshall,West Virginia,FM , +444.075000,449.07500,+,123.0,123.0,KC8FZH,"Moundsville - Grand Vue State Park",Marshall,West Virginia,FM Fusion , +440.900000,445.90000,+,67.0,67.0,W2GSA,"Middletown",Monmouth,New Jersey,FM , +445.975000,440.97500,-,88.5,88.5,NJ5R,"Clark",Union,New Jersey,FM , +146.730000,146.13000,-,100.0,100.0,KC8CSE,"Alderson - Keeney Knob",Summers,West Virginia,FM , +147.000000,147.60000,+,100.0,100.0,WV8CH,"Alderson - Keeney Mtn",Summers,West Virginia,FM , +444.725000,449.72500,+,100.0,100.0,KR8AM,"Alderson - Keeney Mtn",Summers,West Virginia,FM , +442.550000,447.55000,+,100.0,100.0,N3FCK,"Scranton",Lackawanna,Pennsylvania,FM , diff --git a/server.py b/server.py new file mode 100644 index 0000000..1950ddd --- /dev/null +++ b/server.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 +""" +Web control panel server for the ICOM ID-5100. + +Holds one CI-V serial connection (so don't run cli.py at the same time), +serves the instrument-panel UI, and exposes a tiny JSON API on top of radio.py. + + python3 server.py [--port 8550] [--serial /dev/ttyUSB0] [--baud 9600] + +Then browse to http://:8550/ (binds 0.0.0.0 -> reachable from phone). +""" +import argparse +import json +import os +import threading +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer + +from radio import Radio, CIVError + +HERE = os.path.dirname(os.path.abspath(__file__)) +PANEL = os.path.join(HERE, "panel.html") + +radio = None +lock = threading.Lock() + + +def read_status(): + with lock: + freq = radio.get_frequency() + mode, code = radio.get_mode() + return { + "ok": True, + "freq_mhz": round(freq / 1e6, 5), + "mode": mode, + "mode_code": code, + "volume": radio.get_volume(), + "squelch_level": radio.get_squelch_level(), + "squelch_open": radio.squelch_open(), + "smeter": radio.get_smeter(), + } + + +def apply_control(path, body): + with lock: + if path == "/api/freq": + radio.set_frequency(int(round(float(body["mhz"]) * 1e6))) + elif path == "/api/mode": + radio.set_mode(str(body["mode"])) + elif path == "/api/vol": + radio.set_volume(int(body["value"])) + elif path == "/api/sql": + radio.set_squelch_level(int(body["value"])) + else: + raise CIVError("unknown control") + return {"ok": True} + + +class Handler(BaseHTTPRequestHandler): + def log_message(self, *a): + pass # quiet + + def _json(self, obj, code=200): + payload = json.dumps(obj).encode() + self.send_response(code) + self.send_header("Content-Type", "application/json") + self.send_header("Content-Length", str(len(payload))) + self.end_headers() + self.wfile.write(payload) + + def do_GET(self): + if self.path == "/" or self.path == "/index.html": + with open(PANEL, "rb") as f: + body = f.read() + self.send_response(200) + self.send_header("Content-Type", "text/html; charset=utf-8") + self.send_header("Content-Length", str(len(body))) + self.end_headers() + self.wfile.write(body) + elif self.path == "/api/status": + try: + self._json(read_status()) + except (CIVError, OSError) as e: + self._json({"ok": False, "error": str(e)}, 200) + else: + self._json({"ok": False, "error": "not found"}, 404) + + def do_POST(self): + length = int(self.headers.get("Content-Length", 0)) + try: + body = json.loads(self.rfile.read(length) or b"{}") + self._json(apply_control(self.path, body)) + except (CIVError, OSError, ValueError, KeyError) as e: + self._json({"ok": False, "error": str(e)}, 200) + + +def main(): + global radio + ap = argparse.ArgumentParser() + ap.add_argument("--port", type=int, default=8550) + ap.add_argument("--serial", default="/dev/ttyUSB0") + ap.add_argument("--baud", type=int, default=9600) + args = ap.parse_args() + + radio = Radio(args.serial, args.baud).open() + httpd = ThreadingHTTPServer(("0.0.0.0", args.port), Handler) + print(f"ID-5100 panel on http://0.0.0.0:{args.port}/ " + f"(serial {args.serial} @ {args.baud})") + try: + httpd.serve_forever() + except KeyboardInterrupt: + pass + finally: + radio.close() + + +if __name__ == "__main__": + main() diff --git a/test_civ.py b/test_civ.py new file mode 100644 index 0000000..e07df5d --- /dev/null +++ b/test_civ.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +"""Unit tests for the pure CI-V codec (civ.py). Stdlib only: `python3 -m unittest`.""" +import unittest + +import civ + + +class TestFreqCodec(unittest.TestCase): + # Real capture from the radio: VFO was 147.300000 MHz. + REAL_BCD = bytes.fromhex("0000304701") + REAL_HZ = 147_300_000 + + def test_bcd_to_freq_decodes_real_capture(self): + self.assertEqual(civ.bcd_to_freq(self.REAL_BCD), self.REAL_HZ) + + def test_freq_to_bcd_matches_real_capture(self): + self.assertEqual(civ.freq_to_bcd(self.REAL_HZ), self.REAL_BCD) + + def test_freq_roundtrip(self): + for hz in (146_520_000, 446_000_000, 147_300_000, 1_240_000_000): + self.assertEqual(civ.bcd_to_freq(civ.freq_to_bcd(hz)), hz) + + +class TestLevelCodec(unittest.TestCase): + # ICOM levels are 0..255 sent as 2-byte BCD "0000".."0255". + def test_level_to_bcd_known(self): + self.assertEqual(civ.level_to_bcd(0), b"\x00\x00") + self.assertEqual(civ.level_to_bcd(128), b"\x01\x28") + self.assertEqual(civ.level_to_bcd(255), b"\x02\x55") + + def test_bcd_to_level_known(self): + self.assertEqual(civ.bcd_to_level(b"\x00\x00"), 0) + self.assertEqual(civ.bcd_to_level(b"\x01\x28"), 128) + self.assertEqual(civ.bcd_to_level(b"\x02\x55"), 255) + + def test_level_rejects_out_of_range(self): + with self.assertRaises(ValueError): + civ.level_to_bcd(256) + with self.assertRaises(ValueError): + civ.level_to_bcd(-1) + + +class TestBuildFrame(unittest.TestCase): + def test_read_freq_frame(self): + # FE FE 03 FD + self.assertEqual(civ.build_frame(0x03), bytes.fromhex("fefe8ce003fd")) + + def test_frame_with_data(self): + # set freq 147.3 MHz: FE FE 8C E0 05 <5 BCD> FD + frame = civ.build_frame(0x05, civ.freq_to_bcd(147_300_000)) + self.assertEqual(frame, bytes.fromhex("fefe8ce005" + "0000304701" + "fd")) + + +class TestParseFrames(unittest.TestCase): + # Exact bytes the radio returned during the probe (echo + reply). + REAL_RX = bytes.fromhex("fefe8ce003fd" + "fefee08c030000304701fd") + + def test_splits_echo_and_reply(self): + frames = civ.parse_frames(self.REAL_RX) + self.assertEqual(len(frames), 2) + echo, reply = frames + self.assertEqual((echo.to, echo.frm, echo.cn), (0x8C, 0xE0, 0x03)) + self.assertEqual(echo.data, b"") + self.assertEqual((reply.to, reply.frm, reply.cn), (0xE0, 0x8C, 0x03)) + self.assertEqual(reply.data, bytes.fromhex("0000304701")) + + def test_ignores_leading_noise_and_partial_tail(self): + noisy = b"\x00\xff" + self.REAL_RX + b"\xfe\xfe\x99" # partial frame at end + frames = civ.parse_frames(noisy) + self.assertEqual(len(frames), 2) + + def test_empty_buffer(self): + self.assertEqual(civ.parse_frames(b""), []) + + +if __name__ == "__main__": + unittest.main()