Skip to content

feat(spot): POTA as a polled spot source (FR-SPOT-08) - #196

Merged
dc0sk merged 3 commits into
mainfrom
feat/spot-more-networks
Sep 21, 2026
Merged

dc0sk merged 3 commits into
mainfrom
feat/spot-more-networks

Conversation

@dc0sk

@dc0sk dc0sk commented Sep 21, 2026

Copy link
Copy Markdown
Owner

What

Reads the four networks FR-SPOT-08 names (R-EXT-05) and builds POTA. SOTA, WSPRnet and FreeDV Reporter are not built: each is blocked on a decision or prerequisite recorded in OP-7 items 5–7.

  • k4-spot::pota — strict parser for the observed reply (kHz string → Hz, UTC time, park in the comment). A bad record costs only itself; anything that is not a list of flat records is an error shown to the operator.
  • k4-spot::polled — source for polled networks. The request runs on its own thread so a slow server never delays RBN/PSK; injected fetcher, interval, backoff, hung-request deadline, window and per-reply caps.
  • app/src/http_fetch.rs — anonymous bounded GET (timeout, size cap that refuses rather than truncates, no redirects) on the existing ureq/rustls.
  • Fourth worker slot, PotaPrefs (off by default, 30 s–1 h, default 60 s), a POTA section in Networks, green nameplates, demo spots, K4_POTA_URL test hook (http(s) only, otherwise ignored).
  • The worker now rests between passes; with only a polled source it would have spun a core.

Findings worth a look

  • POTA's API docs are an empty placeholder; the schema is from one observation (recorded in R-EXT-05).
  • Bugs the tests found in my own code: a 302 counted as success once redirects were off; ureq treats a body that reaches its limit as over it; the worker spin above.
  • Sabotage: every new test mutated; six results needed a second look (one was a real hole in a size-cap test, fixed). One equivalent mutation is kept and documented.

Verified

fmt, clippy --all-features, full workspace tests (bounded), cargo xtask trace gate OK. Run end to end in --demo against a local stand-in: 2 requests in 40 s at a 30 s interval, expected headers only, green nameplate drawn, out-of-view spot not drawn.

Validation parked with DC0SK (not done here)

  • Enable POTA against the real service (HTTPS) and confirm spots draw; check the status line says "last request succeeded". — Confirmed 2026-09-22 on the live K4: real activator spots draw as green nameplates and click-to-tune lands on them correctly (status-line wording not specifically checked).
  • Confirm spotTime is UTC (compare a spot's age against pota.app).
  • Watch what expire and invalid mean in practice.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Ma4bQKqGNFTYyVSEKPcXRk

dc0sk and others added 2 commits September 21, 2026 08:52
Read the four networks FR-SPOT-08 names (R-EXT-05) and built POTA.

- k4-spot::pota: strict parser for the observed reply (kHz string to Hz,
  UTC time, park in the comment); a bad record costs only itself, anything
  that is not a list of flat records is an error shown to the operator.
- k4-spot::polled: source for polled networks; the request runs on its own
  thread so a slow server never delays the other sources; injected fetcher,
  interval, backoff, hung-request deadline, window and per-reply caps.
- app/src/http_fetch.rs: anonymous bounded GET (timeout, size cap, no
  redirects) on the existing ureq/rustls.
- Fourth worker slot, PotaPrefs (off by default, 30 s..1 h, default 60 s),
  a POTA section in Networks, green nameplates, demo spots.
- The worker now rests between passes; with only a polled source it would
  have spun a core.

SOTA, WSPRnet and FreeDV Reporter are not built; each is blocked on a
decision or prerequisite recorded in OP-7 (items 5-7).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ma4bQKqGNFTYyVSEKPcXRk
An earlier note said FreeDV Reporter needs TLS. That was an assumption. SDRoxide's
public source (read for interface facts only, per R-EXT-04) connects over plain
ws:// in a read-only view role. Also records what it does about POTA (same
endpoint), SOTA (a different, unstable host; no credential) and WSPRnet (own
callsign only).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ma4bQKqGNFTYyVSEKPcXRk
…stants

The boundary inputs of the POTA parser tests were built from the constants they
test (MAX_BODY + 1, MAX_SPOTS + 1), so changing a constant moved the test with it
and nothing noticed. Mutating the constants themselves showed MAX_BODY, MAX_SPOTS,
the frequency ceiling and the default poll interval all unpinned.

The limits are now written as numbers (512 KiB, 2000 spots, 64-character text,
300 GHz plus one hertz, 30 s / 60 s / 1 h). MAX_TOKEN stays an equivalent
mutation: the same 64 is applied again downstream by sanitise_text, and a string
there is a borrowed slice; documented in the code.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ma4bQKqGNFTYyVSEKPcXRk
@dc0sk
dc0sk merged commit 55da39d into main Sep 21, 2026
5 checks passed
@dc0sk
dc0sk deleted the feat/spot-more-networks branch September 22, 2026 08:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant