This repository was archived by the owner on Jul 14, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpersistent_client.py
More file actions
157 lines (124 loc) · 5.82 KB
/
Copy pathpersistent_client.py
File metadata and controls
157 lines (124 loc) · 5.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env python3
import socket
import time
import csv
import logging
from datetime import datetime
from typing import Optional
class PersistentADSBClient:
def __init__(self, host: str = "data.adsbhub.org", port: int = 5002):
self.host = host
self.port = port
self.socket = None
self.running = False
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('persistent_adsb.log'),
logging.StreamHandler()
]
)
self.logger = logging.getLogger(__name__)
self.csv_file = None
self.csv_writer = None
self.message_count = 0
self.connection_attempts = 0
self._setup_csv_output()
def _setup_csv_output(self):
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"persistent_adsb_data_{timestamp}.csv"
self.csv_file = open(filename, 'w', newline='')
self.csv_writer = csv.writer(self.csv_file)
headers = ['timestamp', 'raw_message']
self.csv_writer.writerow(headers)
self.csv_file.flush()
self.logger.info(f"Created output file: {filename}")
self.output_filename = filename
def connect(self) -> bool:
try:
if self.socket:
self.socket.close()
self.connection_attempts += 1
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.settimeout(15)
self.socket.connect((self.host, self.port))
self.logger.info(f"Connected to {self.host}:{self.port} (attempt #{self.connection_attempts})")
return True
except Exception as e:
self.logger.error(f"Connection attempt #{self.connection_attempts} failed: {e}")
return False
def disconnect(self):
if self.socket:
self.socket.close()
self.socket = None
def save_raw_message(self, message: str):
timestamp = datetime.now().isoformat()
self.csv_writer.writerow([timestamp, message.strip()])
self.csv_file.flush()
self.message_count += 1
def run_persistent(self, duration_minutes: int = 5):
self.running = True
end_time = time.time() + (duration_minutes * 60)
buffer = ""
self.logger.info(f"Starting persistent collection for {duration_minutes} minutes...")
while self.running and time.time() < end_time:
if not self.connect():
self.logger.info("Connection failed, waiting 30 seconds before retry...")
time.sleep(30)
continue
try:
# Set a longer timeout for data reception
self.socket.settimeout(120) # 2 minutes
connection_start = time.time()
no_data_timeout = 60 # Give up on this connection after 60s of no data
while time.time() < end_time and (time.time() - connection_start) < no_data_timeout:
try:
data = self.socket.recv(4096).decode('utf-8', errors='ignore')
if not data:
self.logger.info("Connection closed by server")
break
# Reset connection timer since we got data
connection_start = time.time()
buffer += data
# Process complete lines
while '\n' in buffer:
line, buffer = buffer.split('\n', 1)
line = line.rstrip('\r')
if line.strip():
self.save_raw_message(line)
if self.message_count == 1:
self.logger.info(f"First message received: {line.strip()}")
if self.message_count % 100 == 0:
elapsed = time.time() - connection_start
self.logger.info(f"Received {self.message_count} messages")
except socket.timeout:
self.logger.info("Socket timeout, will retry connection...")
break
except Exception as e:
self.logger.error(f"Error receiving data: {e}")
break
self.disconnect()
if time.time() < end_time:
self.logger.info("Waiting 10 seconds before reconnection...")
time.sleep(10)
except KeyboardInterrupt:
self.logger.info("Interrupted by user")
break
if self.csv_file:
self.csv_file.close()
self.logger.info(f"Collection completed: {self.message_count} messages, {self.connection_attempts} connection attempts")
return self.message_count > 0
def main():
print("Persistent ADS-B Data Client")
print("Will attempt multiple connections over 5 minutes")
print("Press Ctrl+C to stop early")
client = PersistentADSBClient()
success = client.run_persistent(duration_minutes=5)
if success:
print(f"\nSuccess! Collected {client.message_count} messages")
print(f"Output file: {client.output_filename}")
else:
print("No data collected - check logs for details")
if __name__ == "__main__":
main()