The Point

Why OMEGA Exists.

Live ocean data is scarce. The instruments that gather it (official scientific moorings) are expensive, so there are very few of them. For most stretches of coast there is no real-time measurement at all: if you want to know what the water is doing at your harbor, reef, or research site, you usually get a forecast model's guess instead of a reading.

OMEGA changes who gets to measure the ocean. A research lab, a harbor, a school, or a sailing community can put their own sensors in the water (readings like water temperature, air pressure, and position) and watch their own patch of sea live: when the temperature spikes, when the swell turns, when a storm arrives. The system also pulls in the official public feeds (NOAA buoys, tide gauges, ocean models), so your hardware and the government's appear side by side on the same map.

And because every reading is cryptographically signed and the network is an open federation anyone can join, what one operator measures can be shared with (and trusted by) everyone else. Many affordable, verifiable eyes on the ocean, instead of a few expensive ones.

The Evidence

Three Things It Has Actually Done.

Start with results. All three came out of this system's own hardware and pipeline, and each one is written up in full on the pages that follow.

Validation

It Agrees With NOAA

When OMEGA's science pipeline and the government's official buoys watched the same ocean, they matched with a correlation of 0.965–0.971 across 12 stations: near-perfect agreement, from hardware that costs a tiny fraction of an official mooring.

Detection

It Caught a Storm Turning

Running its own statistics over wave data at NOAA buoy 46013, OMEGA pinpointed the exact moment the sea state shifted (June 8, 2026, a 0.77 m drop in wave height), the kind of change a harbormaster actually cares about. See the detection →

Sensitivity

It Heard the Atmosphere Breathe

The whole atmosphere rises and falls twice a day: a planet-scale "tide" of air. A $50 OMEGA barometer logged 104,939 readings, and the pipeline resolved that tide at its textbook 11.99-hour period, standing ~580,000× above the noise. See the spectrum →

One engineer, the entire stack

The buoy firmware, the radio mesh that carries the data, the shore gateway that makes sense of it, the science tools, and the 3D globe you explore it in: every layer on these pages was designed and built end to end by one person. Every layer can be opened up and explained by the person who built it.

The Core Idea

A Reading Means the Same Thing, However It Arrives.

A reading should mean the same thing no matter how it reached you: by radio, by cable, or over the internet. Everything else hangs on that. In the program's words, "the standard is the protocol, not the box." The data's meaning (its envelope) is kept separate from the exact format it happens to travel in (its wire form).

That single decision is what makes OMEGA open: an 8-channel radio receiver, a sailboat's SignalK navigation feed, and The Things Network all joined the mesh with zero protocol changes; they feed the same ingest contract, and boats and third-party networks become first-class OMEGA stations. The envelope standardizes identity, time, location, and payload, while the format shifts to fit each link: a dense 84-byte packet over radio, plain JSON over the internet, other formats for specialized receivers.

How It Works

Follow One Reading, Wave to Screen.

Follow one water-temperature reading on its journey, from a probe bobbing offshore to a 3D globe on someone's laptop. Four layers, each doing exactly one job and handing off cleanly to the next.

1. A probe takes the reading. A solar-charged buoy (an ESP32 microcontroller with GPS and sensors, sipping about 60 mA from a single 18650 cell) samples the water and writes the reading to its own flash first. It never waits on the network: at sea, waiting for a reply that never comes would hang the node, so the firmware makes no blocking network calls at all. Saltwater corrodes contacts, waves physically block radio, winter starves the solar panel; the firmware is written assuming all of it.

2. The mesh carries it ashore. The reading is packed into an 84-byte binary frame (it would be 283 bytes as plain JSON, a 70% cut), batched with its neighbors, and moved by store-and-forward: each node holds data until a real route appears (a relay on a headland, a passing node acting as a "data mule"), then hands it off. Urgency picks the radio: a critical alarm goes out instantly over whatever's fastest (cellular, Wi-Fi HaLow), while routine readings wait for the cheap, low-power LoRa link. If every native path fails, frames can even ride foreign open meshes like Meshtastic, under a firmware-enforced airtime guardrail that keeps it legal and polite.

3. The shore gateway makes sense of it. A Python service on a Raspberry-Pi-class box catches the frame, checks its cryptographic signature, and "inflates" those 84 bytes back into the full standard envelope. It lands in a single-file SQLite database running in write-ahead mode: bursts of packets can't lock it up, and the entire deployment's data is one file you can copy to a USB stick for a complete backup. The same gateway pulls NOAA buoys, tide gauges, and public marine models into the identical format, so public data and OMEGA's own hardware sit side by side, queryable the same way.

4. The globe shows it. In the browser, a 3D Earth: scrub time backward, slice the ocean by depth, click any buoy. Real measurements render solid and sharp; forecasts render as soft, flowing particles; you can always tell them apart at a glance. And the layers protect each other: if the portal goes down the gateway keeps buffering, if the gateway goes down the buoys keep logging to flash. A failure stays where it starts.

Decoupled by design

Each layer only knows about its neighbor. That's why a dead laptop on shore never costs you a night of ocean data; the buoys and the gateway carry on alone until it returns.

Experimental

Acoustic / JANUS Bearer (Designed, Not Deployed)

A software-defined, JANUS-interop acoustic bearer is scaffolded as an opt-in transport for subsurface relays (~11.5 kHz, under 5 km range, ~80 bps). The LoRa mesh, gateway, and portal layers have field evidence behind them. This one has no field evidence: it has only been exercised in simulation, and no ADCP, sonde, or acoustic-modem hardware has been deployed. It is presented here as a designed extension to the bearer-agnostic envelope, not as built infrastructure.

Inside Each Layer
graph TD
    subgraph Layer 1: Surface Mesh
        B0[Sensor Probe] -->|UART| B1[Surface Buoy Relay]
        B1 -->|TLV Encoding| B2[LoRa 900MHz SX1262 / LR1121]
        B2 -->|CSMA-CA CSS| B3((Marine RF Link))
    end

    subgraph Layer 2: Mesh Transport
        B3 -->|DTN Carry / Forward| T1[Binary TLV + Batching]
    end

    subgraph Layer 3: Shore Gateway
        T1 -->|RF Reception| C1[Python ASGI Receiver]
        C1 -->|Pub/Sub Queue| C2[Service Layer]
        C2 -->|QC Range Math| C3[(SQLite WAL Database)]
    end

    subgraph Layer 4: Mission Portal
        C3 -->|REST JSON| D1[FastAPI Routers]
        D1 -->|WebSockets| D2[React DOM Client]
        D2 -->|Throttle Hooks| D3[3D WebGL Digital Twin]
    end
Data Flow

The Journey, End to End.

flowchart LR E1(Buoy) -->|LoRa| DTN E3(Node) -->|LoRa| DTN E2(Relay) -->|LoRa| DTN DTN{Mesh
84-byte frames} -->|CSMA-CA| GW GW[Shore gateway
verify ยท store] -->|HTTP| UI((3D globe)) classDef default fill:#0a0f1d,stroke:#9aa2b1,stroke-width:1px,color:#9aa2b1; classDef node fill:#101529,stroke:#3b82f6,stroke-width:2px,color:#fff; class E1,E2,E3,GW,UI node;
The Hard Problems

What Actually Made This Difficult.

The architecture above reads clean. Getting there wasn't. These are the fights that shaped the design: each one a real problem, hit in practice, with the fix that shipped.

Radio

Two Radios, Total Silence

The problem: the buoys use one LoRa chip (Semtech SX1262), the relays a newer one (LR1121). On paper they speak the same language; out of the box they decoded 0% of each other's frames: the chips default to subtly different sync words, checksums, and signal-inversion settings, and any one mismatch means dead air. The fix: force every radio onto the public 0x34 sync word, disable Low Data Rate Optimization, and align CRC and IQ-inversion across both chip families. That took the link from nothing to ~50% of frames decoding on the bench. Honestly a working link, not a solved problem; closing the gap is ongoing.

Bandwidth

Fitting the Ocean Into 84 Bytes

The problem: a marine radio link trickles a few hundred bits per second, and the law limits how long you may transmit. A reading as ordinary JSON is 283 bytes, too fat to send every few seconds. The fix: a custom binary format that carries the same reading in 84 bytes, plus batching that sends the first value in full and then only each tiny change from reading to reading, rebuilt losslessly on shore. Same science, a fraction of the airtime.

Trust

Signing Numbers Two Computers Agree On

The problem: to sign a reading, sender and verifier must produce byte-identical text, but decimals break that. Python writes a coordinate as 1e-07, JavaScript as 0.0000001: same number, different bytes, signature dead. The fix: ban decimals from the signed form entirely. Time in whole seconds, position in millionths of a degree, depth in millimeters: whole numbers only, reproduced identically by a $30 microcontroller and a cloud server. Full story in the trust model below.

Survival

Nothing Is Allowed to Wait

The problem: normal networking assumes a reply is coming. At sea, batteries die in cold water, waves eat radio signals, and salt corrodes seals; nodes will vanish mid-conversation, and any code waiting on them hangs forever. The fix: a Delay Tolerant Network. No blocking calls anywhere in the firmware; every reading is safe in flash before any transmission is attempted; data moves only when a route genuinely exists. Brief connectivity windows get fully used, and the long silent stretches cost nothing but patience.

More war stories

The relay that transmitted perfectly but never received (fixed by one line), the route-planner that sent a boat 13,000 miles the wrong way around the planet, the map that hung because the browser ran out of connections; each is written up honestly in the Engineering Journal →

Trust Model

Only Real Measurements, Each One Signed.

An ocean instrument is only scientifically useful if you can always tell a measurement from a forecast. OMEGA enforces an "Absolute Data Purity" rule: the live map shows only real, deployed hardware and real measurements. Missing data renders as an honest gap, never quietly filled in with a forecast. Each measurement is cryptographically signed at the source, a tamper-proof seal that travels with the data and marks it as genuine.

The Problem

Cross-Language Float Bugs

Cryptographically signing a JSON payload containing floating-point numbers is notoriously brittle. Python might serialize a coordinate as 1e-07 while a JavaScript node emits 0.0000001. The data is identical, but the string representation differs, breaking the signature verification and making cross-platform trust impossible.

The Solution

Float-Free Ed25519 Envelopes

Each reading is signed at the source with a standard scheme (Ed25519) over a stripped-down text form that uses only whole numbers (time in whole seconds, position in millionths of a degree, depth in millimeters) and rejects any decimals outright. This guarantees that signed bytes are 100% reproducible on a $30 microcontroller and a cloud server alike, securing the federation against spoofed readings.

Federation

An Open, Multi-Operator Network.

OMEGA runs as an open network of independently-run gateways. Identity is rooted in cryptography, and joining is zero-config: a gateway mints its own key, and that key is its credential.

Zero-Config Join

Self-Minted Identity

On first boot a gateway mints a persistent Ed25519 keypair. Its gateway_id is the key fingerprint, so identity cannot be forged or reassigned. The node self-signs an identity card and joins with no operator-issued token: it generates a key, self-registers, announces, and proves key-possession to peers.

Data-Sharing Policy

Federation Directory

A federation directory records each peer and a per-peer data-sharing policy (public, partners, or private) with explicit revocation. Operators decide who sees their feed; a revoked peer stops receiving shared observations.

Contributor Reputation

A Transparent Contribution Rank (0–100)

A 0–100 reputation rank is computed transparently from the public sightings ledger: volume, reach, recency, and longevity of a contributor's data. It is deliberately a contribution rank, not a trust gate: it surfaces who is feeding the network, and is not used to admit or block peers. Its quality-control sub-score is honestly inactive today and stays dark until per-reading QC lands.

Design Decisions

Why Python over Go or Rust?

For a telemetry gateway handling raw binary bytes, compiled languages like Rust or Go look like the obvious choice. OMEGA runs on Python anyway, and the reason is who uses it.

The Trade-off

Speed vs Science

Python is slower than C++ or Rust. OMEGA's target audience is marine biologists, climatologists, and university researchers. With the entire gateway in Python, researchers can plug pandas, scipy, and numpy models directly into the pipeline without learning a systems language. The network exists for them; the language choice follows.

The Mitigation

Async Everywhere

To offset the speed penalty, the gateway is built on FastAPI and Python's asyncio event loop, with strictly non-blocking I/O: every database query and web request yields instead of stalling. For a network whose radios deliver bytes at a trickle, that concurrency is more than enough.

Why SQLite over PostgreSQL?

Conventional wisdom says a serious backend needs a "real" database server running in its own container. OMEGA deliberately uses a single SQLite file, which at sea is the safer bet.

The Constraint: the gateway often runs on a Raspberry-Pi-class board on a pitching vessel, where waves over the solar panel can cut power without warning; and SD cards are notorious for corrupting under exactly that abuse.

The Decision: a Docker daemon with a PostgreSQL volume is a lot of moving machinery to trust to a fragile SD card. SQLite compiles directly into the Python process (no daemon at all) and the whole database is one physical .db file, so a field operator can copy omega.db to a USB stick and hold a complete, air-gapped backup of the entire deployment. Write-ahead mode (PRAGMA journal_mode=WAL) removes SQLite's classic locking limits: the safety of a flat file with the speed of a networked database.

Why a 3D Globe on the GPU?

OMEGA renders the map the way a video game does: hand all the points to the graphics card (the GPU) at once. A normal web map (like Leaflet) draws every dot as its own little web-page element, which holds up for a handful of pins and grinds the browser to a halt once you pile on thousands of historical readings.

graph LR L[Leaflet.js] -->|a node per point| D[Thousands
of DOM nodes] --> Crash[Browser
bogs down] R[React state] -->|array buffer| W[WebGL] --> G[GPU canvas] --> Fast[Render
on change] classDef default fill:#0a0f1d,stroke:#9aa2b1,stroke-width:1px,color:#9aa2b1; classDef bad fill:#3f1010,stroke:#ef4444,stroke-width:2px,color:#fff; classDef good fill:#101529,stroke:#3b82f6,stroke-width:2px,color:#fff; class Crash bad; class Fast good;

The Decision: the portal uses a self-hosted CesiumJS 3D globe that bypasses the browser's DOM, passing coordinate buffers directly to the GPU via WebGL. To keep a laptop responsive it renders on-change rather than in a fixed loop, with time-stepped overlays for playing history back.

Honest status: the 3D digital twin (DTO v3) is partial and in-flight; first load is currently on the order of 30–60 seconds. Pushing into the millions-of-points regime via a Deck.gl layer is a roadmap goal, not shipped today.

Roadmap: Deck.gl Point Layer Sketch
import { DeckGL } from '@deck.gl/react';
import { ScatterplotLayer } from '@deck.gl/layers';

// Roadmap sketch: a GPU point layer for dense historical telemetry
function TelemetryMap({ data }) {
  const layer = new ScatterplotLayer({
    id: 'telemetry-layer',
    data,
    // WebGL bypasses the DOM and injects directly to the GPU
    getPosition: d => [d.longitude, d.latitude],
    getFillColor: d => {
      // Color map based on raw temperature
      if (d.temperature > 25) return [239, 68, 68]; // Red
      return [59, 130, 246]; // Blue
    },
    getRadius: d => 10,
    radiusUnits: 'pixels',
    pickable: true
  });

  return (
    <DeckGL
      initialViewState={{ longitude: -157, latitude: 21, zoom: 6 }}
      controller={true}
      layers={[layer]}
    />
  );
}
Operator Self-Service

Let Operators Add Their Own Formulas, Safely.

Operators frequently need custom derived metrics (e.g., dewpoint, heat index, density) calculated on the fly without writing backend code. The naive approach is running Python's eval() on the server, which is a serious code-injection vulnerability on a public gateway.

The Solution: The backend implements a custom Abstract Syntax Tree (AST) interpreter for derived metrics. It parses and validates mathematical formulas at definition time, explicitly allowing only numeric literals and a whitelisted set of math operations (sqrt, sin, log). Attribute access, function calls, and import tricks are rejected at parse time. Operators get full mathematical expressiveness, and anything outside that whitelist never runs.

Engineering Reality / Readiness

Where the Stack Actually Stands.

An honest read of where the stack is strong and where it isn't: the protocol, gateway, and portal carry real field evidence; the alternate bearers and the edge firmware's field-hardening are the least mature parts.

Honest Gaps

Multi-hop mesh routing is implemented but not yet field-demonstrated; cross-family RF interop is a working ~50% link rather than a solved problem; firmware field-hardening is written but unflashed; and the 3D twin is partial. The single-hop LoRa link, the gateway, and the portal are where the real field evidence lives.