Skip to content

Commit 96675a9

Browse files
feat: Iridium pass predictor + queue proxy (Priorities 3d + 4)
Priority 3d — queue proxy: - 4 new proxy handlers in communication.go: GetMeshsatIridiumQueue, PostMeshsatIridiumQueue, PostMeshsatIridiumQueueCancel, PostMeshsatIridiumQueuePriority - Routes: /communication/meshsat/iridium/queue and sub-paths Priority 4 — server-side pass predictor: - Schema migration v26: iridium_locations table (with Leiden + Thessaloniki seeds) and iridium_tle_cache table - tle_manager.go: daily Celestrak TLE fetch, SGP4 pass computation via github.com/akhenakh/sgp4, location CRUD, cache info - 5 new handlers: GetIridiumPasses, PostIridiumPassesRefresh, GetIridiumLocations, PostIridiumLocation, DeleteIridiumLocation - Routes: /communication/iridium/passes, /communication/iridium/passes/refresh, /communication/iridium/locations (CRUD) - main.go: wire TLEManager + SetTLEManager on CommunicationHandler Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 6888812 commit 96675a9

6 files changed

Lines changed: 711 additions & 2 deletions

File tree

cmd/cubeos-api/main.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,13 @@ func main() {
589589
defer signalRecorder.Stop()
590590
log.Info().Msg("Iridium signal recorder started")
591591

592+
// Start Iridium TLE manager (daily Celestrak fetch + SGP4 pass prediction)
593+
tleManager := managers.NewTLEManager(db.DB)
594+
tleManager.Start(engineCtx)
595+
defer tleManager.Stop()
596+
communicationHandler.SetTLEManager(tleManager)
597+
log.Info().Msg("Iridium TLE manager started")
598+
592599
// Create WebSocket manager and handlers
593600
wsManager := handlers.NewWSManager(systemMgr, networkMgr, monitoringMgr, docker)
594601
wsHandlers := handlers.NewWSHandlers(wsManager)

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ require (
2222
require (
2323
github.com/KyleBanks/depth v1.2.1 // indirect
2424
github.com/Microsoft/go-winio v0.6.2 // indirect
25+
github.com/akhenakh/sgp4 v0.0.0-20250910232432-ca28846088fc // indirect
2526
github.com/containerd/log v0.1.0 // indirect
2627
github.com/distribution/reference v0.6.0 // indirect
2728
github.com/docker/go-connections v0.5.0 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc
66
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
77
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
88
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
9+
github.com/akhenakh/sgp4 v0.0.0-20250910232432-ca28846088fc h1:MuvZBPt391TvmQGeyKbaFM8y13OqW+Lp1bGhx/izMbg=
10+
github.com/akhenakh/sgp4 v0.0.0-20250910232432-ca28846088fc/go.mod h1:JfAepWD223Cel6uRpzYdip/xijWZ2FT457YFLWy8Md4=
911
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
1012
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
1113
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=

internal/database/migrations.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,44 @@ var migrations = []Migration{
10151015
return nil
10161016
},
10171017
},
1018+
{
1019+
Version: 26,
1020+
Description: "Add Iridium pass predictor tables: locations and TLE cache",
1021+
Up: func(db *sql.DB) error {
1022+
stmts := []string{
1023+
// iridium_locations: ground stations for pass prediction
1024+
`CREATE TABLE IF NOT EXISTS iridium_locations (
1025+
id INTEGER PRIMARY KEY AUTOINCREMENT,
1026+
name TEXT NOT NULL,
1027+
lat REAL NOT NULL,
1028+
lon REAL NOT NULL,
1029+
alt_m REAL NOT NULL DEFAULT 0,
1030+
builtin INTEGER NOT NULL DEFAULT 0,
1031+
created_at INTEGER NOT NULL DEFAULT (CAST(strftime('%s','now') AS INTEGER))
1032+
)`,
1033+
// Seed built-in locations
1034+
`INSERT OR IGNORE INTO iridium_locations (name, lat, lon, alt_m, builtin) VALUES ('Leiden', 52.160, 4.497, 0, 1)`,
1035+
`INSERT OR IGNORE INTO iridium_locations (name, lat, lon, alt_m, builtin) VALUES ('Thessaloniki', 40.629, 22.947, 0, 1)`,
1036+
1037+
// iridium_tle_cache: cached TLE data fetched from Celestrak
1038+
`CREATE TABLE IF NOT EXISTS iridium_tle_cache (
1039+
id INTEGER PRIMARY KEY AUTOINCREMENT,
1040+
satellite_name TEXT NOT NULL,
1041+
line1 TEXT NOT NULL,
1042+
line2 TEXT NOT NULL,
1043+
fetched_at INTEGER NOT NULL -- Unix epoch seconds
1044+
)`,
1045+
`CREATE INDEX IF NOT EXISTS idx_tle_cache_name ON iridium_tle_cache(satellite_name)`,
1046+
}
1047+
for _, stmt := range stmts {
1048+
if _, err := db.Exec(stmt); err != nil {
1049+
return fmt.Errorf("migration 26 failed: %w\nStatement: %s", err, stmt)
1050+
}
1051+
}
1052+
log.Info().Msg("Migration 26: Created iridium_locations and iridium_tle_cache tables")
1053+
return nil
1054+
},
1055+
},
10181056
}
10191057

10201058
// isDuplicateColumnError checks if an error is a "duplicate column" error

0 commit comments

Comments
 (0)