Skip to content
sapiqa

Edge · LoRa · offline-first

A water-sports centre that sees every student on the water, even without internet

LoRa GPS trackers, an edge server on the beach, safety zones with alarms and a full booking system with OTA channels. Safety runs locally; the cloud helps when there is a link.

Status
Deployed: a base on Mykonos and a demo in Poland
Period
April – October 2026
LoRa range over water measured in a field test, straight to the gateway
2,5 kmLoRa range over water measured in a field test, straight to the gateway
with a solar repeater on the roof: design range, line of sight over water
up to 8 kmwith a solar repeater on the roof: design range, line of sight over water
open ports: internet access only through Cloudflare Tunnel
0open ports: internet access only through Cloudflare Tunnel
FastAPI endpoints
198FastAPI endpoints

The problem

A beach has no reliable internet, yet the instructor has to know where every student is: who drifted too far, who hasn't moved for fifteen minutes, whose kit is coming back. On top of that come bookings, waivers, rentals and OTA channels, all of which usually live in a spreadsheet and three apps.

What I built

  • Meshtastic GPS trackers (SenseCAP T1000-E) send positions over 868 MHz LoRa to a WIO L1 Pro gateway next to the server. A solar repeater extends the range.
  • A NucBox (mini PC) on the beach: FastAPI, PostgreSQL, InfluxDB, nginx, its own DNS and DHCP on the LAN, HTTPS with a Let's Encrypt certificate. Tablets run the PWA without internet too, with an offline map.
  • Geofencing in the packet receiver: leaving the safe zone or entering a no-go zone raises the same alarm as SOS. Zones are drawn in a map editor, per skill level.
  • Water sessions with timer, pause and automatic splitting. A tracker belongs to a session, not to a customer. Rentals with a QR scanner and label printing on a Niimbot printer over Bluetooth, straight from the browser.
  • Multi-tenant cloud panel: Google calendars, Stripe, Bókun (Viator and other OTAs: push, availability, webhooks), waivers with eIDAS e-signature via firma.dev and offline signing.
  • An “Ask AI” agent in the owner's panel reads sessions, kit and telemetry, answers by voice (ElevenLabs) and reports on the mesh. A demo factory builds a booking site for a new school from its URL alone.

Architecture

The interesting part is underneath

Pick a flow to see data move through the system. Click any part for details.

← swipe the diagram →

WATER · LORA 868 MHZBEACH · NUCBOX, WORKS OFFLINECLOUD · WHEN THERE IS A LINKT1000-EGPS tracker + SOSSolar P1-Prosolar repeaterWIO L1 ProLoRa gateway → USBreceive.pyreceiver + geofenceInfluxDBtelemetry and tracksFastAPIsessions, kit, alarmsPostgreSQLoperational datanginx · dnsmasqLAN, HTTPS, DNSLive · CMSPWA on a tabletNiimbot B1QR labels (BLE)Cloudflare Tunneloutbound, no open portsbook. · panel.Droplet, multi-tenantStripepaymentsBókunOTA, Viatorfirma.deveIDAS waiversClaudeAsk AI agentElevenLabsvoiceAgent fleetoversight (plan)

Flows

The alarm reaches the instructor without the internet.

Step 1 of 6

Click a part of the diagram for details.

  • hardware
  • edge / network
  • service
  • data
  • AI
  • third party
  • people / apps
  • radio
  • tunnel
  • HTTPS
  • local
  • event
Every element, described
T1000-E · GPS tracker + SOS
A Meshtastic tracker on the student's arm. Sends a position every 30 s (shorter intervals clogged the channel and lost telemetry) and has an SOS button. The whole fleet is configured by one script, about a minute per tracker.
Solar P1-Pro · solar repeater
A SenseCAP Solar repeater on a mast. Monitored: no signal for 3 h shows as a fault in the “Mesh health” panel.
WIO L1 Pro · LoRa gateway → USB
A gateway permanently plugged into the NucBox over USB. In a field test it received trackers 2.5 km away over water, with zero mesh hops. With a SenseCAP P1-Pro solar repeater on the roof (5.8 dBi antenna, self-powered) the design range grows to 3–8 km line of sight.
receive.py · receiver + geofence
A separate systemd service. Decodes packets, matches nodes to trackers in the database, checks every position with point-in-polygon against the zones and raises events: SOS, zone breach, GPS silence.
InfluxDB · telemetry and tracks
Time series of positions and telemetry. Session history and analytics are built from it.
FastAPI · sessions, kit, alarms
The core: customers, sessions, rentals, zones, events. Base configuration (brand, currency, map) comes from one file, so the same install serves Mykonos, Hel or a demo.
PostgreSQL · operational data
Customers, sessions, kit (79 items in a season), bookings synced from the cloud. Backups from a timer.
nginx · dnsmasq · LAN, HTTPS, DNS
The beach router hands out addresses and dnsmasq points the domain at the NucBox, so tablets open the same domain with a valid certificate even with no internet.
Live · CMS · PWA on a tablet
Live map with zones, alarms, registration, a customer card with QR, check-in. Installed as a PWA, with an offline map downloaded by one button.
Niimbot B1 · QR labels (BLE)
A label printer driven from the browser over Web Bluetooth: kit labels and customer cards, in bulk too.
Cloudflare Tunnel · outbound, no open ports
The NucBox dials out to Cloudflare, so the beach router has no port forwarding and no open ports. The admin panel sits behind Cloudflare Access.
book. · panel. · Droplet, multi-tenant
Online booking and the owner's panel, multi-tenant. Bookings sync to the NucBox when there is a link; the beach never waits for the cloud.
Stripe · payments
Deposit or full payment at booking. Plan: Stripe Connect Express, so each school connects its own account in 5 minutes.
Bókun · OTA, Viator
OAuth and REST v2 integration: pushing products, prices, availability, photos and the booking webhook.
firma.dev · eIDAS waivers
Waivers signed electronically before going on the water, with an offline version on the tablet.
Claude · Ask AI agent
An agent with read-only tools: sessions, kit, telemetry, mesh health. It has a cost budget and shows anything that needs approval for confirmation.
ElevenLabs · voice
Agent answers and “read the situation” on the map, spoken aloud. Fixed phrases are cached on the NucBox, so they play offline too.
Agent fleet · oversight (plan)
Design: a cheap model watches 20+ sites continuously, a stronger one steps in on anomalies, and fixes arrive as PRs for approval.

Decisions that make the difference

Safety does not depend on the cloud

The whole tracker → alarm path runs on the LAN. The cloud provides bookings and the agent, but its failure never switches off SOS.

A tracker belongs to a session, not a customer

One tracker passes through many students a day. Binding it to a session keeps history correct and avoids mix-ups at hand-out.

Air-time capacity is physics, not config

Meshtastic channels don't add capacity. Scaling means separate frequencies on several gateways, and beyond that TDMA timed by GPS on custom firmware.

One codebase, many sites

Brand, currency, map and contact live in config. A demo for a new school is scraped from its website in minutes.

How it works

Four apps, one system

Most centres juggle a booking tool, a spreadsheet, paper waivers and a WhatsApp group. SurfCenter replaces all of it with four connected apps and one source of truth.

CMS: check-in for rentals and lessons, customer cards, QR equipment and analytics.

A session with timer and tracker

Data on the screens is fictional.

Stack

PythonFastAPIPostgreSQLInfluxDBReactPWAMapboxMeshtasticLoRanginxdnsmasqsystemdCloudflare TunnelStripeBókunClaudeElevenLabsWeb Bluetooth

Service lines

Got a process that should run itself?

30 minutes, free. I'll tell you if it makes sense, how I'd build it and what it would cost to run.

Book a call