Fix issue #21 and add aircraft position tracking indicators
- Fix Debian package upgrade issue by separating upgrade vs remove behavior in prerm script - Add aircraft position tracking statistics in merger GetStatistics() method - Update frontend to display position tracking indicators in both header and stats view - Format Go code to maintain consistency 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
0db12a1ddc
commit
66a995b4d0
8 changed files with 124 additions and 74 deletions
|
|
@ -36,7 +36,7 @@ type VRSClient struct {
|
|||
errChan chan error // Error reporting channel
|
||||
stopChan chan struct{} // Shutdown signal channel
|
||||
wg sync.WaitGroup // Wait group for goroutine coordination
|
||||
|
||||
|
||||
// Reconnection parameters
|
||||
reconnectDelay time.Duration // Initial reconnect delay
|
||||
maxReconnect time.Duration // Maximum reconnect delay (for backoff cap)
|
||||
|
|
@ -116,9 +116,9 @@ func (c *VRSClient) Stop() {
|
|||
// Source status is updated to reflect connection state for monitoring
|
||||
func (c *VRSClient) run(ctx context.Context) {
|
||||
defer c.wg.Done()
|
||||
|
||||
|
||||
reconnectDelay := c.reconnectDelay
|
||||
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
|
|
@ -127,16 +127,16 @@ func (c *VRSClient) run(ctx context.Context) {
|
|||
return
|
||||
default:
|
||||
}
|
||||
|
||||
|
||||
// Connect to VRS JSON stream
|
||||
addr := fmt.Sprintf("%s:%d", c.source.Host, c.source.Port)
|
||||
fmt.Printf("Connecting to VRS JSON stream at %s (%s)...\n", addr, c.source.Name)
|
||||
|
||||
|
||||
conn, err := net.DialTimeout("tcp", addr, 30*time.Second)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to connect to VRS source %s: %v\n", c.source.Name, err)
|
||||
c.source.Active = false
|
||||
|
||||
|
||||
// Exponential backoff
|
||||
time.Sleep(reconnectDelay)
|
||||
if reconnectDelay < c.maxReconnect {
|
||||
|
|
@ -144,21 +144,21 @@ func (c *VRSClient) run(ctx context.Context) {
|
|||
}
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
c.conn = conn
|
||||
c.source.Active = true
|
||||
reconnectDelay = c.reconnectDelay // Reset backoff
|
||||
|
||||
|
||||
fmt.Printf("Connected to VRS source %s at %s\n", c.source.Name, addr)
|
||||
|
||||
|
||||
// Create parser for this connection
|
||||
c.parser = vrs.NewParser(conn, c.source.ID)
|
||||
|
||||
|
||||
// Start processing messages
|
||||
c.wg.Add(2)
|
||||
go c.readMessages()
|
||||
go c.processMessages()
|
||||
|
||||
|
||||
// Wait for disconnect
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
|
|
@ -172,7 +172,7 @@ func (c *VRSClient) run(ctx context.Context) {
|
|||
c.conn.Close()
|
||||
c.source.Active = false
|
||||
}
|
||||
|
||||
|
||||
// Wait for goroutines to finish
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
|
|
@ -206,7 +206,7 @@ func (c *VRSClient) readMessages() {
|
|||
// and conflict resolution based on signal strength
|
||||
func (c *VRSClient) processMessages() {
|
||||
defer c.wg.Done()
|
||||
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-c.stopChan:
|
||||
|
|
@ -215,7 +215,7 @@ func (c *VRSClient) processMessages() {
|
|||
if msg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Process each aircraft in the message
|
||||
for _, vrsAircraft := range msg.AcList {
|
||||
// Convert VRS aircraft to internal format
|
||||
|
|
@ -223,7 +223,7 @@ func (c *VRSClient) processMessages() {
|
|||
if aircraft == nil {
|
||||
continue // Skip invalid aircraft
|
||||
}
|
||||
|
||||
|
||||
// Update merger with new data
|
||||
// Note: VRS doesn't provide signal strength, so we use a default value
|
||||
c.merger.UpdateAircraft(
|
||||
|
|
@ -232,7 +232,7 @@ func (c *VRSClient) processMessages() {
|
|||
-30.0, // Default signal strength for VRS sources
|
||||
vrsAircraft.GetTimestamp(),
|
||||
)
|
||||
|
||||
|
||||
// Update source statistics
|
||||
c.source.Messages++
|
||||
}
|
||||
|
|
@ -258,75 +258,75 @@ func (c *VRSClient) convertVRSToAircraft(vrs *vrs.VRSAircraft) *modes.Aircraft {
|
|||
if err != nil {
|
||||
return nil // Invalid ICAO, skip this aircraft
|
||||
}
|
||||
|
||||
|
||||
// Create aircraft structure
|
||||
aircraft := &modes.Aircraft{
|
||||
ICAO24: icao,
|
||||
}
|
||||
|
||||
|
||||
// Set position if available
|
||||
if vrs.HasPosition() {
|
||||
aircraft.Latitude = vrs.Lat
|
||||
aircraft.Longitude = vrs.Long
|
||||
aircraft.PositionValid = true
|
||||
}
|
||||
|
||||
|
||||
// Set altitude if available
|
||||
if vrs.HasAltitude() {
|
||||
aircraft.Altitude = vrs.GetAltitude()
|
||||
aircraft.AltitudeValid = true
|
||||
|
||||
|
||||
// Set barometric altitude specifically
|
||||
if vrs.Alt != 0 {
|
||||
aircraft.BaroAltitude = vrs.Alt
|
||||
}
|
||||
|
||||
|
||||
// Set geometric altitude if different from barometric
|
||||
if vrs.GAlt != 0 {
|
||||
aircraft.GeomAltitude = vrs.GAlt
|
||||
aircraft.GeomAltitudeValid = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set speed if available
|
||||
if vrs.Spd > 0 {
|
||||
aircraft.GroundSpeed = int(vrs.Spd)
|
||||
aircraft.GroundSpeedValid = true
|
||||
}
|
||||
|
||||
|
||||
// Set heading/track if available
|
||||
if vrs.Trak > 0 {
|
||||
aircraft.Track = int(vrs.Trak)
|
||||
aircraft.TrackValid = true
|
||||
}
|
||||
|
||||
|
||||
// Set vertical rate if available
|
||||
if vrs.Vsi != 0 {
|
||||
aircraft.VerticalRate = vrs.Vsi
|
||||
aircraft.VerticalRateValid = true
|
||||
}
|
||||
|
||||
|
||||
// Set callsign if available
|
||||
if vrs.Call != "" {
|
||||
aircraft.Callsign = vrs.Call
|
||||
aircraft.CallsignValid = true
|
||||
}
|
||||
|
||||
|
||||
// Set squawk if available
|
||||
if squawk, err := vrs.GetSquawk(); err == nil {
|
||||
aircraft.Squawk = fmt.Sprintf("%04X", squawk) // Convert to hex string
|
||||
aircraft.SquawkValid = true
|
||||
}
|
||||
|
||||
|
||||
// Set ground status
|
||||
aircraft.OnGround = vrs.IsOnGround()
|
||||
aircraft.OnGroundValid = true
|
||||
|
||||
|
||||
// Set selected altitude if available
|
||||
if vrs.TAlt != 0 {
|
||||
aircraft.SelectedAltitude = vrs.TAlt
|
||||
}
|
||||
|
||||
|
||||
// Set position source
|
||||
switch vrs.GetPositionSource() {
|
||||
case "MLAT":
|
||||
|
|
@ -334,7 +334,7 @@ func (c *VRSClient) convertVRSToAircraft(vrs *vrs.VRSAircraft) *modes.Aircraft {
|
|||
case "TIS-B":
|
||||
aircraft.PositionTISB = true
|
||||
}
|
||||
|
||||
|
||||
// Set additional metadata if available
|
||||
if vrs.Reg != "" {
|
||||
aircraft.Registration = vrs.Reg
|
||||
|
|
@ -345,6 +345,6 @@ func (c *VRSClient) convertVRSToAircraft(vrs *vrs.VRSAircraft) *modes.Aircraft {
|
|||
if vrs.Op != "" {
|
||||
aircraft.Operator = vrs.Op
|
||||
}
|
||||
|
||||
|
||||
return aircraft
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue