Quickstart
Stand up the smallest server a QuickComm device is happy with, point a unit at it, and watch real 16 kHz audio arrive — in about thirty minutes, on your own infrastructure.
9 min read
On this page
This is the shortest path that proves every layer works: the device reaches your server, your server understands what it sent, and audio lands where you can act on it. Do it once, in order, before you write a line of your own business logic. Most integration pain is somebody debugging their intent extraction against a device that was never actually online.
1. Stand up the smallest server that works
A factory-flashed device needs exactly one endpoint to be happy — a heartbeat — plus a socket for whichever transport its mode selects. This file is both, in about forty lines. Run it on a machine the device can reach.
import asyncio, datetime as dt, json
from http.server import BaseHTTPRequestHandler, HTTPServer
from threading import Thread
SEEN = {} # mac -> last heartbeat, so you can watch presence
class Fleet(BaseHTTPRequestHandler):
def _json(self, code, body):
raw = json.dumps(body).encode()
self.send_response(code)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(raw)))
self.end_headers()
self.wfile.write(raw)
def do_POST(self):
if self.path != "/api/devices/heartbeat":
return self._json(404, {"detail": "not found"})
n = int(self.headers.get("Content-Length", 0))
beat = json.loads(self.rfile.read(n) or b"{}")
mac = beat.get("mac_address", "").upper()
SEEN[mac] = dt.datetime.now(dt.timezone.utc)
print("heartbeat", mac, beat.get("firmware_version"), beat.get("wifi_rssi"))
# pending_commands 0 tells the device not to bother polling for commands.
self._json(200, {"status": "ok",
"last_seen_at": SEEN[mac].isoformat(),
"pending_commands": 0})
def do_GET(self):
self._json(200, {"status": "ok"}) if self.path == "/health" \
else self._json(404, {"detail": "not found"})
def log_message(self, *a):
pass # the prints above are the interesting output
class Ingest(asyncio.DatagramProtocol):
def datagram_received(self, data, addr):
nl = data.find(b"\x0a")
if nl < 1:
return # not udp-v1; skip, never raise
meta = data[:nl].decode("ascii", "ignore").split(",")
pcm = data[nl + 1:]
if len(meta) < 9 or meta[0] != "v1" or not pcm:
return
print(f"audio seq={meta[1]} session={meta[2]} mac={meta[3]} "
f"property={meta[5]} bytes={len(pcm)}")
# ── everything below this line is YOUR product ──────────────────
# recogniser(f"{meta[3]}|{meta[2]}").feed(pcm)
async def udp():
loop = asyncio.get_running_loop()
await loop.create_datagram_endpoint(Ingest, local_addr=("0.0.0.0", 12345))
await asyncio.Event().wait()
Thread(target=HTTPServer(("0.0.0.0", 8000), Fleet).serve_forever, daemon=True).start()
print("fleet plane on :8000, udp-v1 ingest on :12345")
asyncio.run(udp())python3 quickcomm_min.py
# fleet plane on :8000, udp-v1 ingest on :12345
# In another shell — the LAN address the device must reach:
ipconfig getifaddr en0 # macOS
hostname -I | awk '{print $1}' # Linux2. Prove your server answers before you involve hardware
If these two commands do not behave, the device will not either — and you will spend the next hour blaming the device.
HOST=http://192.168.1.50:8000
MAC=AA:BB:CC:DD:EE:FF
curl -s -X POST $HOST/api/devices/heartbeat \
-H "Content-Type: application/json" \
-d "{\"mac_address\":\"$MAC\",\"firmware_version\":\"2.1.4\"}"
# → {"status":"ok","last_seen_at":"...","pending_commands":0}
printf 'v1,1,probe01,%s,2,4,7,19,\n0000000000' "$MAC" \
| nc -u -w1 192.168.1.50 12345
# the server prints: audio seq=1 session=probe01 mac=AA:BB:... bytes=103. Point the device at your server
Every device ships with a QR provisioning card. The payload it carries is what the device writes into non-volatile storage and keeps across reboots — including the address of the server it will talk to.
http://192.168.4.1/?mac_address=AA:BB:CC:DD:EE:FF
&property_id=4
&organization_id=2
&team_id=7
&comm_mode=udp
&mode=local ← your server, not a managed one
&local_ip=192.168.1.50
&local_port=8000
&ssid=YourWiFi
&password=...- 1Power the device on. It boots into SoftAP mode and publishes a captive portal at 192.168.4.1.
- 2Join that access point with a phone and scan the QR card from the box.
- 3The phone opens the URL. The device writes the query string into non-volatile storage and reboots.
- 4It joins your Wi-Fi and starts heartbeating your server every 30 seconds.
4. Watch it arrive
Within thirty seconds of the reboot your terminal should print a heartbeat line. Hold the button and speak, and it should print audio lines as fast as the capture buffers fill.
heartbeat AA:BB:CC:DD:EE:FF 2.1.4 -58
audio seq=0 session=b7f3a1c2 mac=AA:BB:CC:DD:EE:FF property=4 bytes=640
audio seq=1 session=b7f3a1c2 mac=AA:BB:CC:DD:EE:FF property=4 bytes=640
audio seq=2 session=b7f3a1c2 mac=AA:BB:CC:DD:EE:FF property=4 bytes=640
heartbeat AA:BB:CC:DD:EE:FF 2.1.4 -575. Turn audio into something
The line marked YOUR product above is where your stack begins. Key a recognition session on mac and device_session so a reboot starts a new session rather than joining the last one, and feed it the PCM as it arrives.
SESSIONS = {}
def datagram_received(self, data, addr):
...
key = f"{meta[3]}|{meta[2]}" # mac | device_session
stream = SESSIONS.get(key)
if stream is None:
stream = SESSIONS[key] = my_stt.open(sample_rate=16000, encoding="s16le")
stream.on_final = lambda text: my_logic(text, property_id=int(meta[5]))
stream.feed(pcm)Any provider that accepts a live 16 kHz signed 16-bit little-endian mono stream will work, hosted or local. The device has no opinion.
Where to go from here
- 1The minimum server — the full endpoint contract, including commands, incidents and OTA.
- 2The page for your mode: push-to-talk streaming, request and response, or full-duplex agent.
- 3Building your business logic — eight worked verticals on the same firmware.
- 4Acceptance tests — twenty-seven pass/fail tests that define integrated.
Something wrong or missing on this page? Tell us.

