API Reference
BlueOS Extension API
blueos-extension (:8099)
HTTP Endpoints
GET /health
Health check endpoint.
Response:
{
"status": "healthy",
"serial": true,
"frames": 12345,
"protocol": "binary_v4"
}
GET /api/latest
Get latest sensor frame (JSON).
Response: Full sensor frame (see Architecture → JSON frame output)
GET /api/dvl
Get DVL (Doppler Velocity Log) state.
Response:
{
"vx": 0.0,
"vy": 0.0,
"vz": 0.0,
"valid": false
}
GET /api/ctd
Get CTD data (Conductivity, Temperature, Depth).
Response:
{
"timestamp": "2026-03-27T17:00:00",
"depth_m": 5.2,
"temperature_c": 15.3,
"conductivity_us": 42000.0,
"salinity_psu": 35.5,
"sound_velocity_ms": 1485.7,
"pressure_mbar": 1520.0
}
GET /api/status
System status and statistics.
Response:
{
"frames": 12345,
"clients": 2,
"port": "/dev/ttyUSB0",
"serial_connected": true,
"log": "/app/logs/session_20260327_170000.jsonl",
"ws_port": 8766,
"crc_errors": 3,
"protocol": "binary_v4",
"udp_targets": ["127.0.0.1"],
"mavlink_enabled": true,
"mavlink_target": "192.168.2.2:14401",
"mavlink_sent": 5432
}
WebSocket (port 8766)
Real-time sensor frames (JSON), published at ~2Hz.
Message format: Same as /api/latest response.
Example client (JavaScript):
const ws = new WebSocket('ws://192.168.0.174:8766');
ws.onmessage = (event) => {
const frame = JSON.parse(event.data);
console.log('IMU:', frame.imu);
console.log('Depth:', frame.depth);
};
UDP Forwarding
Port 14555: Kogger A raw BB55 frames
Port 14556: Kogger B raw BB55 frames
Target: Kogger App desktop viewer
MAVLink Output
Port 14401: MAVLink v2 messages to ArduPilot
Messages: ATTITUDE (#30), SCALED_PRESSURE (#29), GPS_RAW_INT (#24)
Kogger Viewer API
kogger-viewer (:8100)
HTTP Endpoints
GET /health
Health check.
Response:
{
"status": "healthy",
"a_packets": 1234,
"a_bytes": 123456,
"a_bb55": 1200,
"a_pings": 150,
"b_packets": 1150,
"b_bytes": 115000,
"b_bb55": 1100,
"b_pings": 140
}
GET /api/status
Detailed stats.
Response:
{
"a_packets": 1234,
"a_bytes": 123456,
"a_bb55": 1200,
"a_pings": 150,
"b_packets": 1150,
"b_bytes": 115000,
"b_bb55": 1100,
"b_pings": 140,
"clients": 1,
"ws_port": 8101
}
POST /api/kogger_cmd
Forward Kogger command to ESP32 → Kogger device.
Request:
{
"port": 14570,
"data": "base64_encoded_bb55_command"
}
Response:
{
"status": "ok",
"port": 14570,
"bytes": 42
}
WebSocket (port 8101)
Real-time waterfall ping data.
Message format:
{
"ch": "A",
"amp": "base64_encoded_amplitude_200_bytes",
"n": 1234
}
Fields:
ch: Channel (“A” or “B”)amp: Base64-encoded 200-byte amplitude arrayn: Ping sequence number
Example client (JavaScript):
const ws = new WebSocket('ws://192.168.0.174:8101');
ws.onmessage = (event) => {
const ping = JSON.parse(event.data);
const ampData = atob(ping.amp); // decode base64
// Render waterfall line...
};
Environment Variables
blueos-extension
Variable |
Default |
Description |
|---|---|---|
|
|
ESP32 serial port |
|
|
Serial baud rate |
|
|
WebSocket port |
|
|
HTTP server port |
|
|
Comma-separated Kogger UDP targets |
|
|
Enable MAVLink bridge (0/1) |
|
|
MAVLink destination IP |
|
|
MAVLink destination port |
|
(empty) |
External CTD logger URL |
kogger-viewer
Variable |
Default |
Description |
|---|---|---|
|
|
HTTP server port |
|
|
WebSocket port |
|
|
Kogger A UDP listen port |
|
|
Kogger B UDP listen port |
Data Logging
JSONL Log Format
Location: /app/logs/session_YYYYMMDD_HHMMSS.jsonl
Each line is a JSON sensor frame with added timestamp:
{
"_t": "2026-03-27T17:00:00.123456",
"ts": 12345,
"imu": {...},
"gps": {...},
"depth": {...},
"...": "..."
}
Log Rotation
New log file created on service restart
No automatic rotation (manual cleanup recommended)
Logs persisted to
/usr/blueos/extensions/slam-hubon host