Clean up codebase and fix server host binding for IPv6 support
Cleanup: - Remove unused aircraft-icon.svg (replaced by type-specific icons) - Remove test files: beast-dump-with-heli.bin, beast.test, main, old.json, ux.png - Remove duplicate config.json.example (kept config.example.json) - Remove empty internal/coverage/ directory - Move CLAUDE.md to project root - Update assets.go documentation to reflect current icon structure - Format all Go code with gofmt Server Host Binding Fix: - Fix critical bug where server host configuration was ignored - Add host parameter to Server struct and NewWebServer constructor - Rename NewServer to NewWebServer for better clarity - Fix IPv6 address formatting in server binding (wrap in brackets) - Update startup message to show correct bind address format - Support localhost-only, IPv4, IPv6, and interface-specific binding This resolves the "too many colons in address" error for IPv6 hosts like ::1 and enables proper localhost-only deployment as configured. Closes #15 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
67d0e0612a
commit
0d60592b9f
16 changed files with 266 additions and 289 deletions
|
|
@ -111,7 +111,7 @@ func (a *AircraftState) MarshalJSON() ([]byte, error) {
|
|||
SelectedAltitude int `json:"SelectedAltitude"`
|
||||
SelectedHeading float64 `json:"SelectedHeading"`
|
||||
BaroSetting float64 `json:"BaroSetting"`
|
||||
|
||||
|
||||
// From AircraftState
|
||||
Sources map[string]*SourceData `json:"sources"`
|
||||
LastUpdate time.Time `json:"last_update"`
|
||||
|
|
@ -155,7 +155,7 @@ func (a *AircraftState) MarshalJSON() ([]byte, error) {
|
|||
SelectedAltitude: a.Aircraft.SelectedAltitude,
|
||||
SelectedHeading: a.Aircraft.SelectedHeading,
|
||||
BaroSetting: a.Aircraft.BaroSetting,
|
||||
|
||||
|
||||
// Copy all fields from AircraftState
|
||||
Sources: a.Sources,
|
||||
LastUpdate: a.LastUpdate,
|
||||
|
|
@ -238,7 +238,7 @@ type Merger struct {
|
|||
sources map[string]*Source // Source ID -> source information
|
||||
icaoDB *icao.Database // ICAO country lookup database
|
||||
mu sync.RWMutex // Protects all maps and slices
|
||||
historyLimit int // Maximum history points to retain
|
||||
historyLimit int // Maximum history points to retain
|
||||
staleTimeout time.Duration // Time before aircraft considered stale (15 seconds)
|
||||
updateMetrics map[uint32]*updateMetric // ICAO24 -> update rate calculation data
|
||||
}
|
||||
|
|
@ -291,13 +291,13 @@ func (m *Merger) AddSource(source *Source) {
|
|||
// UpdateAircraft merges new aircraft data from a source using intelligent fusion strategies.
|
||||
//
|
||||
// This is the core method of the merger, handling:
|
||||
// 1. Aircraft state creation for new aircraft
|
||||
// 2. Source data tracking and statistics
|
||||
// 3. Multi-source data fusion with conflict resolution
|
||||
// 4. Historical data updates with retention limits
|
||||
// 5. Distance and bearing calculations
|
||||
// 6. Update rate metrics
|
||||
// 7. Source status maintenance
|
||||
// 1. Aircraft state creation for new aircraft
|
||||
// 2. Source data tracking and statistics
|
||||
// 3. Multi-source data fusion with conflict resolution
|
||||
// 4. Historical data updates with retention limits
|
||||
// 5. Distance and bearing calculations
|
||||
// 6. Update rate metrics
|
||||
// 7. Source status maintenance
|
||||
//
|
||||
// Data fusion strategies:
|
||||
// - Position: Use source with strongest signal
|
||||
|
|
@ -326,7 +326,7 @@ func (m *Merger) UpdateAircraft(sourceID string, aircraft *modes.Aircraft, signa
|
|||
AltitudeHistory: make([]AltitudePoint, 0),
|
||||
SpeedHistory: make([]SpeedPoint, 0),
|
||||
}
|
||||
|
||||
|
||||
// Lookup country information for new aircraft
|
||||
icaoHex := fmt.Sprintf("%06X", aircraft.ICAO24)
|
||||
if countryInfo, err := m.icaoDB.LookupCountry(icaoHex); err == nil {
|
||||
|
|
@ -339,7 +339,7 @@ func (m *Merger) UpdateAircraft(sourceID string, aircraft *modes.Aircraft, signa
|
|||
state.CountryCode = "XX"
|
||||
state.Flag = "🏳️"
|
||||
}
|
||||
|
||||
|
||||
m.aircraft[aircraft.ICAO24] = state
|
||||
m.updateMetrics[aircraft.ICAO24] = &updateMetric{
|
||||
updates: make([]time.Time, 0),
|
||||
|
|
@ -585,10 +585,10 @@ func (m *Merger) updateHistories(state *AircraftState, aircraft *modes.Aircraft,
|
|||
// updateUpdateRate calculates and maintains the message update rate for an aircraft.
|
||||
//
|
||||
// The calculation:
|
||||
// 1. Records the timestamp of each update
|
||||
// 2. Maintains a sliding 30-second window of updates
|
||||
// 3. Calculates updates per second over this window
|
||||
// 4. Updates the aircraft's UpdateRate field
|
||||
// 1. Records the timestamp of each update
|
||||
// 2. Maintains a sliding 30-second window of updates
|
||||
// 3. Calculates updates per second over this window
|
||||
// 4. Updates the aircraft's UpdateRate field
|
||||
//
|
||||
// This provides real-time feedback on data quality and can help identify
|
||||
// aircraft that are updating frequently (close, good signal) vs infrequently
|
||||
|
|
@ -644,10 +644,10 @@ func (m *Merger) getBestSignalSource(state *AircraftState) string {
|
|||
// GetAircraft returns a snapshot of all current aircraft states.
|
||||
//
|
||||
// This method:
|
||||
// 1. Filters out stale aircraft (older than staleTimeout)
|
||||
// 2. Calculates current age for each aircraft
|
||||
// 3. Determines closest receiver distance and bearing
|
||||
// 4. Returns copies to prevent external modification
|
||||
// 1. Filters out stale aircraft (older than staleTimeout)
|
||||
// 2. Calculates current age for each aircraft
|
||||
// 3. Determines closest receiver distance and bearing
|
||||
// 4. Returns copies to prevent external modification
|
||||
//
|
||||
// The returned map uses ICAO24 addresses as keys and can be safely
|
||||
// used by multiple goroutines without affecting the internal state.
|
||||
|
|
@ -813,7 +813,7 @@ func calculateDistanceBearing(lat1, lon1, lat2, lon2 float64) (float64, float64)
|
|||
func (m *Merger) Close() error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
|
||||
if m.icaoDB != nil {
|
||||
return m.icaoDB.Close()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue