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 ("\n Attempting 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 ("\n Finished!" )
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