Skip to content

Commit 1635b7b

Browse files
committed
Add OpenSky-Network API example
Free public limit is 100 calls per day and maximum of 60 seconds each or you'll get temp banned. You get 4000 calls if you login but I haven't figured out how with a microcontroller yet. They have no token system and their API is primarily built for python & curl. It's a foot in the door for public access to flight data.
1 parent 59b1aca commit 1635b7b

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# SPDX-FileCopyrightText: 2023 DJDevon3
2+
# SPDX-License-Identifier: MIT
3+
# Coded for Circuit Python 8.1
4+
"""DJDevon3 Adafruit Feather ESP32-S3 OpenSkyNetwork_API_Example"""
5+
import os
6+
import time
7+
import ssl
8+
import json
9+
import wifi
10+
import socketpool
11+
import adafruit_requests
12+
13+
# No developer account necessary for this API
14+
# OpenSky-Networks.org REST API: https://openskynetwork.github.io/opensky-api/rest.html
15+
# All active flights JSON: https://opensky-network.org/api/states/all
16+
# JSON order: transponder, callsign, country
17+
# ACTIVE transponder you want data from
18+
transponder = "ab1644"
19+
20+
# Initialize WiFi Pool (There can be only 1 pool & top of script)
21+
pool = socketpool.SocketPool(wifi.radio)
22+
23+
# Time between API refreshes
24+
# 900 = 15 mins, 1800 = 30 mins, 3600 = 1 hour
25+
# OpenSky-Networks will temp ban your IP for too many requests, there is a public rate limit.
26+
# https://openskynetwork.github.io/opensky-api/rest.html#limitations
27+
sleep_time = 1800
28+
29+
# this example uses settings.toml for credentials
30+
# timezone offset is in seconds plus or minus GMT
31+
ssid = os.getenv('AP_SSID')
32+
appw = os.getenv('AP_PASSWORD')
33+
timezone = os.getenv('timezone')
34+
tz_offset_seconds = os.getenv('timezone_offset')
35+
36+
# https://opensky-network.org/api/states/all
37+
# example https://opensky-network.org/api/states/all?icao24=a808c5
38+
# You can use states/own to pull your owned craft data without rate limit.
39+
OPENSKY_SOURCE = (
40+
"https://opensky-network.org/api/states/all?"
41+
+ "icao24="
42+
+ transponder
43+
)
44+
45+
def time_calc(input_time):
46+
if input_time < 60:
47+
sleep_int = input_time
48+
time_output = f"{sleep_int:.0f} seconds"
49+
elif 60 <= input_time < 3600:
50+
sleep_int = input_time / 60
51+
time_output = f"{sleep_int:.0f} minutes"
52+
elif 3600 <= input_time < 86400:
53+
sleep_int = input_time / 60 / 60
54+
time_output = f"{sleep_int:.1f} hours"
55+
elif 86400 <= input_time < 432000:
56+
sleep_int = input_time / 60 / 60 / 24
57+
time_output = f"{sleep_int:.1f} days"
58+
else: # if > 5 days convert float to int & display whole days
59+
sleep_int = input_time / 60 / 60 / 24
60+
time_output = f"{sleep_int:.0f} days"
61+
return time_output
62+
63+
def _format_datetime(datetime):
64+
return "{:02}/{:02}/{} {:02}:{:02}:{:02}".format(
65+
datetime.tm_mon,
66+
datetime.tm_mday,
67+
datetime.tm_year,
68+
datetime.tm_hour,
69+
datetime.tm_min,
70+
datetime.tm_sec,
71+
)
72+
73+
# Connect to Wi-Fi
74+
print("\n===============================")
75+
print("Connecting to WiFi...")
76+
requests = adafruit_requests.Session(pool, ssl.create_default_context())
77+
while not wifi.radio.ipv4_address:
78+
try:
79+
wifi.radio.connect(ssid, appw)
80+
except ConnectionError as e:
81+
print("Connection Error:", e)
82+
print("Retrying in 10 seconds")
83+
time.sleep(10)
84+
print("Connected!\n")
85+
86+
while True:
87+
debug_request = True # Set true to see full request
88+
if debug_request:
89+
print("Full API GET URL: ", OPENSKY_SOURCE)
90+
print("===============================")
91+
try:
92+
print("\nAttempting to GET OpenSky-Network Stats!")
93+
opensky_response = requests.get(url=OPENSKY_SOURCE)
94+
osn_json = opensky_response.json()
95+
except (ConnectionError, ValueError, NameError) as e:
96+
print("Host No Response Error:", e)
97+
98+
# Print Full JSON to Serial
99+
debug_response = False # Set true to see full response
100+
if debug_response:
101+
dump_object = json.dumps(osn_json)
102+
print("JSON Dump: ", dump_object)
103+
104+
# Print to Serial
105+
osn_debug_keys = True # Set true to print Serial data
106+
if osn_debug_keys:
107+
try:
108+
osn_flight = osn_json['time']
109+
print("Current Unix Time: ", osn_flight)
110+
111+
current_struct_time = time.localtime(osn_flight)
112+
current_date = "{}".format(_format_datetime(current_struct_time))
113+
print(f"Unix to Readable Time: {current_date}")
114+
115+
osn_single_flight_data = osn_json['states']
116+
if osn_single_flight_data is not None:
117+
print("Flight Data: ", osn_single_flight_data)
118+
transponder = osn_json['states'][0][0]
119+
print("Transponder: ", transponder)
120+
callsign = osn_json['states'][0][1]
121+
print("Callsign: ", callsign)
122+
country = osn_json['states'][0][2]
123+
print("Flight Country: ", country)
124+
else:
125+
print("This flight has no active data or you're polling too fast.")
126+
print("You will eventually get temp banned for polling too fast!")
127+
print("Please read: https://openskynetwork.github.io/opensky-api/rest.html#limitations")
128+
print("Public Limits: 10 second max poll rate & 400 weighted calls daily")
129+
print("There is no JSON error, states/all html page will say \"Too many requests\" and the script will fail ")
130+
131+
print("\nFinished!")
132+
print("Board Uptime: ", time_calc(time.monotonic()))
133+
print("Next Update: ", time_calc(sleep_time))
134+
time.sleep(sleep_time)
135+
print("===============================")
136+
137+
except (ConnectionError, ValueError, NameError) as e:
138+
print("OSN Connection Error:", e)
139+
print("You are likely banned for 24 hours")
140+
print("Next Retry: ", time_calc(sleep_time))
141+
time.sleep(sleep_time)

0 commit comments

Comments
 (0)