ha-opensky-core 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ha_opensky_core-0.1.0/LICENSE +21 -0
- ha_opensky_core-0.1.0/PKG-INFO +144 -0
- ha_opensky_core-0.1.0/README.md +124 -0
- ha_opensky_core-0.1.0/ha_opensky_core.egg-info/PKG-INFO +144 -0
- ha_opensky_core-0.1.0/ha_opensky_core.egg-info/SOURCES.txt +45 -0
- ha_opensky_core-0.1.0/ha_opensky_core.egg-info/dependency_links.txt +1 -0
- ha_opensky_core-0.1.0/ha_opensky_core.egg-info/requires.txt +1 -0
- ha_opensky_core-0.1.0/ha_opensky_core.egg-info/top_level.txt +1 -0
- ha_opensky_core-0.1.0/opensky/__init__.py +0 -0
- ha_opensky_core-0.1.0/opensky/adsbfi_metadata_provider.py +176 -0
- ha_opensky_core-0.1.0/opensky/aircraft_metadata.py +639 -0
- ha_opensky_core-0.1.0/opensky/airport.py +303 -0
- ha_opensky_core-0.1.0/opensky/airport_analyzer.py +266 -0
- ha_opensky_core-0.1.0/opensky/analyzer.py +410 -0
- ha_opensky_core-0.1.0/opensky/approach.py +142 -0
- ha_opensky_core-0.1.0/opensky/approach_history.py +145 -0
- ha_opensky_core-0.1.0/opensky/approach_manager.py +1063 -0
- ha_opensky_core-0.1.0/opensky/approach_report.py +132 -0
- ha_opensky_core-0.1.0/opensky/approach_repository.py +35 -0
- ha_opensky_core-0.1.0/opensky/approach_repository_memory.py +47 -0
- ha_opensky_core-0.1.0/opensky/approach_service.py +193 -0
- ha_opensky_core-0.1.0/opensky/approach_statistics.py +365 -0
- ha_opensky_core-0.1.0/opensky/approach_statistics_summary.py +66 -0
- ha_opensky_core-0.1.0/opensky/approach_summary.py +152 -0
- ha_opensky_core-0.1.0/opensky/approach_tracker.py +445 -0
- ha_opensky_core-0.1.0/opensky/auth.py +104 -0
- ha_opensky_core-0.1.0/opensky/client.py +58 -0
- ha_opensky_core-0.1.0/opensky/data/airports.csv +85846 -0
- ha_opensky_core-0.1.0/opensky/data/runways.csv +48147 -0
- ha_opensky_core-0.1.0/opensky/freshness.py +41 -0
- ha_opensky_core-0.1.0/opensky/geometry.py +187 -0
- ha_opensky_core-0.1.0/opensky/hexdb_metadata_provider.py +168 -0
- ha_opensky_core-0.1.0/opensky/metadata_normalizer.py +187 -0
- ha_opensky_core-0.1.0/opensky/models.py +209 -0
- ha_opensky_core-0.1.0/opensky/parser.py +42 -0
- ha_opensky_core-0.1.0/opensky/photo_provider.py +277 -0
- ha_opensky_core-0.1.0/opensky/planespotters_metadata_provider.py +287 -0
- ha_opensky_core-0.1.0/opensky/runway.py +230 -0
- ha_opensky_core-0.1.0/opensky/runways.py +29 -0
- ha_opensky_core-0.1.0/opensky/sqlite_approach_repository.py +320 -0
- ha_opensky_core-0.1.0/opensky/tests/__init__.py +0 -0
- ha_opensky_core-0.1.0/opensky/tests/test_aircraft_freshness.py +48 -0
- ha_opensky_core-0.1.0/opensky/tests/test_analyzer_freshness.py +156 -0
- ha_opensky_core-0.1.0/opensky/tests/test_freshness.py +43 -0
- ha_opensky_core-0.1.0/opensky/tracker.py +67 -0
- ha_opensky_core-0.1.0/pyproject.toml +44 -0
- ha_opensky_core-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 stego020472
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ha-opensky-core
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Standalone OpenSky OAuth client and aircraft analysis library
|
|
5
|
+
Author: stego020472
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Keywords: opensky,opensky-network,aviation,aircraft,ads-b,oauth,home-assistant
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
15
|
+
Requires-Python: >=3.13
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: requests>=2.32.0
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# ha-opensky-core
|
|
22
|
+
|
|
23
|
+
Standalone Python library for accessing the OpenSky Network API using OAuth authentication and for performing aircraft, airport and approach analysis.
|
|
24
|
+
|
|
25
|
+
The library is designed to be usable independently of Home Assistant. Home Assistant-specific functionality is implemented separately in the `ha-opensky-oauth` integration.
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
* OpenSky Network OAuth authentication
|
|
30
|
+
* Search aircraft within a geographic area
|
|
31
|
+
* Aircraft data models using metric units
|
|
32
|
+
* Aircraft metadata lookup
|
|
33
|
+
* Aircraft photo lookup and fallback providers
|
|
34
|
+
* Airport and runway database
|
|
35
|
+
* Airport and runway analysis
|
|
36
|
+
* Aircraft approach detection and tracking
|
|
37
|
+
* Approach entry and exit transitions
|
|
38
|
+
* Reusable `ApproachService` boundary for frontend applications
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install ha-opensky-core
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Basic usage
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from opensky.client import OpenSkyClient
|
|
50
|
+
from opensky.models import SearchArea
|
|
51
|
+
|
|
52
|
+
area = SearchArea(
|
|
53
|
+
latitude=50.901,
|
|
54
|
+
longitude=4.484,
|
|
55
|
+
radius_km=20,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
client = OpenSkyClient(...)
|
|
59
|
+
|
|
60
|
+
aircraft = client.get_aircraft(area)
|
|
61
|
+
|
|
62
|
+
for item in aircraft:
|
|
63
|
+
print(item.icao24, item.callsign)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The exact authentication and client configuration depends on the OpenSky OAuth credentials available to the application.
|
|
67
|
+
|
|
68
|
+
## Airport database
|
|
69
|
+
|
|
70
|
+
The package contains the airport and runway databases required by the airport analysis functionality.
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from opensky.airport import AirportDatabase
|
|
74
|
+
|
|
75
|
+
db = AirportDatabase()
|
|
76
|
+
|
|
77
|
+
print(db.count())
|
|
78
|
+
|
|
79
|
+
airport = db.require("EBBR")
|
|
80
|
+
print(airport.name)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Architecture
|
|
84
|
+
|
|
85
|
+
`ha-opensky-core` contains the reusable OpenSky functionality and has no dependency on Home Assistant.
|
|
86
|
+
|
|
87
|
+
The architecture is intentionally split into two layers:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
┌──────────────────────────────────────┐
|
|
91
|
+
│ Home Assistant integration │
|
|
92
|
+
│ ha-opensky-oauth │
|
|
93
|
+
└──────────────────┬───────────────────┘
|
|
94
|
+
│
|
|
95
|
+
▼
|
|
96
|
+
┌──────────────────────────────────────┐
|
|
97
|
+
│ ha-opensky-core │
|
|
98
|
+
│ │
|
|
99
|
+
│ OAuth / API / Aircraft / Metadata │
|
|
100
|
+
│ Airports / Runways / Approaches │
|
|
101
|
+
└──────────────────┬───────────────────┘
|
|
102
|
+
│
|
|
103
|
+
▼
|
|
104
|
+
OpenSky Network API
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
This allows the core library to be tested and used independently of Home Assistant.
|
|
108
|
+
|
|
109
|
+
## Development
|
|
110
|
+
|
|
111
|
+
Clone the repository and create a virtual environment:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
python -m venv .venv
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Activate the environment and install the package in editable mode:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
python -m pip install -e .
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Run the available test and diagnostic scripts with:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
python -m scripts.test_oauth
|
|
127
|
+
python -m scripts.test_metadata
|
|
128
|
+
python -m scripts.test_airports
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Requirements
|
|
132
|
+
|
|
133
|
+
* Python 3.13 or newer
|
|
134
|
+
* OpenSky Network OAuth credentials for authenticated API access
|
|
135
|
+
|
|
136
|
+
## Status
|
|
137
|
+
|
|
138
|
+
This project is currently in alpha development.
|
|
139
|
+
|
|
140
|
+
The API may change between releases.
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
MIT License.
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# ha-opensky-core
|
|
2
|
+
|
|
3
|
+
Standalone Python library for accessing the OpenSky Network API using OAuth authentication and for performing aircraft, airport and approach analysis.
|
|
4
|
+
|
|
5
|
+
The library is designed to be usable independently of Home Assistant. Home Assistant-specific functionality is implemented separately in the `ha-opensky-oauth` integration.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
* OpenSky Network OAuth authentication
|
|
10
|
+
* Search aircraft within a geographic area
|
|
11
|
+
* Aircraft data models using metric units
|
|
12
|
+
* Aircraft metadata lookup
|
|
13
|
+
* Aircraft photo lookup and fallback providers
|
|
14
|
+
* Airport and runway database
|
|
15
|
+
* Airport and runway analysis
|
|
16
|
+
* Aircraft approach detection and tracking
|
|
17
|
+
* Approach entry and exit transitions
|
|
18
|
+
* Reusable `ApproachService` boundary for frontend applications
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install ha-opensky-core
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Basic usage
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
from opensky.client import OpenSkyClient
|
|
30
|
+
from opensky.models import SearchArea
|
|
31
|
+
|
|
32
|
+
area = SearchArea(
|
|
33
|
+
latitude=50.901,
|
|
34
|
+
longitude=4.484,
|
|
35
|
+
radius_km=20,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
client = OpenSkyClient(...)
|
|
39
|
+
|
|
40
|
+
aircraft = client.get_aircraft(area)
|
|
41
|
+
|
|
42
|
+
for item in aircraft:
|
|
43
|
+
print(item.icao24, item.callsign)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The exact authentication and client configuration depends on the OpenSky OAuth credentials available to the application.
|
|
47
|
+
|
|
48
|
+
## Airport database
|
|
49
|
+
|
|
50
|
+
The package contains the airport and runway databases required by the airport analysis functionality.
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from opensky.airport import AirportDatabase
|
|
54
|
+
|
|
55
|
+
db = AirportDatabase()
|
|
56
|
+
|
|
57
|
+
print(db.count())
|
|
58
|
+
|
|
59
|
+
airport = db.require("EBBR")
|
|
60
|
+
print(airport.name)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Architecture
|
|
64
|
+
|
|
65
|
+
`ha-opensky-core` contains the reusable OpenSky functionality and has no dependency on Home Assistant.
|
|
66
|
+
|
|
67
|
+
The architecture is intentionally split into two layers:
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
┌──────────────────────────────────────┐
|
|
71
|
+
│ Home Assistant integration │
|
|
72
|
+
│ ha-opensky-oauth │
|
|
73
|
+
└──────────────────┬───────────────────┘
|
|
74
|
+
│
|
|
75
|
+
▼
|
|
76
|
+
┌──────────────────────────────────────┐
|
|
77
|
+
│ ha-opensky-core │
|
|
78
|
+
│ │
|
|
79
|
+
│ OAuth / API / Aircraft / Metadata │
|
|
80
|
+
│ Airports / Runways / Approaches │
|
|
81
|
+
└──────────────────┬───────────────────┘
|
|
82
|
+
│
|
|
83
|
+
▼
|
|
84
|
+
OpenSky Network API
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
This allows the core library to be tested and used independently of Home Assistant.
|
|
88
|
+
|
|
89
|
+
## Development
|
|
90
|
+
|
|
91
|
+
Clone the repository and create a virtual environment:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
python -m venv .venv
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Activate the environment and install the package in editable mode:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
python -m pip install -e .
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Run the available test and diagnostic scripts with:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
python -m scripts.test_oauth
|
|
107
|
+
python -m scripts.test_metadata
|
|
108
|
+
python -m scripts.test_airports
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Requirements
|
|
112
|
+
|
|
113
|
+
* Python 3.13 or newer
|
|
114
|
+
* OpenSky Network OAuth credentials for authenticated API access
|
|
115
|
+
|
|
116
|
+
## Status
|
|
117
|
+
|
|
118
|
+
This project is currently in alpha development.
|
|
119
|
+
|
|
120
|
+
The API may change between releases.
|
|
121
|
+
|
|
122
|
+
## License
|
|
123
|
+
|
|
124
|
+
MIT License.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ha-opensky-core
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Standalone OpenSky OAuth client and aircraft analysis library
|
|
5
|
+
Author: stego020472
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Keywords: opensky,opensky-network,aviation,aircraft,ads-b,oauth,home-assistant
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
15
|
+
Requires-Python: >=3.13
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: requests>=2.32.0
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# ha-opensky-core
|
|
22
|
+
|
|
23
|
+
Standalone Python library for accessing the OpenSky Network API using OAuth authentication and for performing aircraft, airport and approach analysis.
|
|
24
|
+
|
|
25
|
+
The library is designed to be usable independently of Home Assistant. Home Assistant-specific functionality is implemented separately in the `ha-opensky-oauth` integration.
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
* OpenSky Network OAuth authentication
|
|
30
|
+
* Search aircraft within a geographic area
|
|
31
|
+
* Aircraft data models using metric units
|
|
32
|
+
* Aircraft metadata lookup
|
|
33
|
+
* Aircraft photo lookup and fallback providers
|
|
34
|
+
* Airport and runway database
|
|
35
|
+
* Airport and runway analysis
|
|
36
|
+
* Aircraft approach detection and tracking
|
|
37
|
+
* Approach entry and exit transitions
|
|
38
|
+
* Reusable `ApproachService` boundary for frontend applications
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install ha-opensky-core
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Basic usage
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from opensky.client import OpenSkyClient
|
|
50
|
+
from opensky.models import SearchArea
|
|
51
|
+
|
|
52
|
+
area = SearchArea(
|
|
53
|
+
latitude=50.901,
|
|
54
|
+
longitude=4.484,
|
|
55
|
+
radius_km=20,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
client = OpenSkyClient(...)
|
|
59
|
+
|
|
60
|
+
aircraft = client.get_aircraft(area)
|
|
61
|
+
|
|
62
|
+
for item in aircraft:
|
|
63
|
+
print(item.icao24, item.callsign)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The exact authentication and client configuration depends on the OpenSky OAuth credentials available to the application.
|
|
67
|
+
|
|
68
|
+
## Airport database
|
|
69
|
+
|
|
70
|
+
The package contains the airport and runway databases required by the airport analysis functionality.
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from opensky.airport import AirportDatabase
|
|
74
|
+
|
|
75
|
+
db = AirportDatabase()
|
|
76
|
+
|
|
77
|
+
print(db.count())
|
|
78
|
+
|
|
79
|
+
airport = db.require("EBBR")
|
|
80
|
+
print(airport.name)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Architecture
|
|
84
|
+
|
|
85
|
+
`ha-opensky-core` contains the reusable OpenSky functionality and has no dependency on Home Assistant.
|
|
86
|
+
|
|
87
|
+
The architecture is intentionally split into two layers:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
┌──────────────────────────────────────┐
|
|
91
|
+
│ Home Assistant integration │
|
|
92
|
+
│ ha-opensky-oauth │
|
|
93
|
+
└──────────────────┬───────────────────┘
|
|
94
|
+
│
|
|
95
|
+
▼
|
|
96
|
+
┌──────────────────────────────────────┐
|
|
97
|
+
│ ha-opensky-core │
|
|
98
|
+
│ │
|
|
99
|
+
│ OAuth / API / Aircraft / Metadata │
|
|
100
|
+
│ Airports / Runways / Approaches │
|
|
101
|
+
└──────────────────┬───────────────────┘
|
|
102
|
+
│
|
|
103
|
+
▼
|
|
104
|
+
OpenSky Network API
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
This allows the core library to be tested and used independently of Home Assistant.
|
|
108
|
+
|
|
109
|
+
## Development
|
|
110
|
+
|
|
111
|
+
Clone the repository and create a virtual environment:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
python -m venv .venv
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Activate the environment and install the package in editable mode:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
python -m pip install -e .
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Run the available test and diagnostic scripts with:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
python -m scripts.test_oauth
|
|
127
|
+
python -m scripts.test_metadata
|
|
128
|
+
python -m scripts.test_airports
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Requirements
|
|
132
|
+
|
|
133
|
+
* Python 3.13 or newer
|
|
134
|
+
* OpenSky Network OAuth credentials for authenticated API access
|
|
135
|
+
|
|
136
|
+
## Status
|
|
137
|
+
|
|
138
|
+
This project is currently in alpha development.
|
|
139
|
+
|
|
140
|
+
The API may change between releases.
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
MIT License.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
ha_opensky_core.egg-info/PKG-INFO
|
|
5
|
+
ha_opensky_core.egg-info/SOURCES.txt
|
|
6
|
+
ha_opensky_core.egg-info/dependency_links.txt
|
|
7
|
+
ha_opensky_core.egg-info/requires.txt
|
|
8
|
+
ha_opensky_core.egg-info/top_level.txt
|
|
9
|
+
opensky/__init__.py
|
|
10
|
+
opensky/adsbfi_metadata_provider.py
|
|
11
|
+
opensky/aircraft_metadata.py
|
|
12
|
+
opensky/airport.py
|
|
13
|
+
opensky/airport_analyzer.py
|
|
14
|
+
opensky/analyzer.py
|
|
15
|
+
opensky/approach.py
|
|
16
|
+
opensky/approach_history.py
|
|
17
|
+
opensky/approach_manager.py
|
|
18
|
+
opensky/approach_report.py
|
|
19
|
+
opensky/approach_repository.py
|
|
20
|
+
opensky/approach_repository_memory.py
|
|
21
|
+
opensky/approach_service.py
|
|
22
|
+
opensky/approach_statistics.py
|
|
23
|
+
opensky/approach_statistics_summary.py
|
|
24
|
+
opensky/approach_summary.py
|
|
25
|
+
opensky/approach_tracker.py
|
|
26
|
+
opensky/auth.py
|
|
27
|
+
opensky/client.py
|
|
28
|
+
opensky/freshness.py
|
|
29
|
+
opensky/geometry.py
|
|
30
|
+
opensky/hexdb_metadata_provider.py
|
|
31
|
+
opensky/metadata_normalizer.py
|
|
32
|
+
opensky/models.py
|
|
33
|
+
opensky/parser.py
|
|
34
|
+
opensky/photo_provider.py
|
|
35
|
+
opensky/planespotters_metadata_provider.py
|
|
36
|
+
opensky/runway.py
|
|
37
|
+
opensky/runways.py
|
|
38
|
+
opensky/sqlite_approach_repository.py
|
|
39
|
+
opensky/tracker.py
|
|
40
|
+
opensky/data/airports.csv
|
|
41
|
+
opensky/data/runways.csv
|
|
42
|
+
opensky/tests/__init__.py
|
|
43
|
+
opensky/tests/test_aircraft_freshness.py
|
|
44
|
+
opensky/tests/test_analyzer_freshness.py
|
|
45
|
+
opensky/tests/test_freshness.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
requests>=2.32.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
opensky
|
|
File without changes
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ADSB.fi aircraft metadata provider.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
|
|
10
|
+
import requests
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
_LOGGER = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
ADSBFI_AIRCRAFT_URL = (
|
|
17
|
+
"https://opendata.adsb.fi/api/v2/hex/{icao24}"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
ADSBFI_USER_AGENT = (
|
|
21
|
+
"ha-opensky-oauth/1.0 "
|
|
22
|
+
"(https://github.com/stego020472/ha-opensky-oauth)"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass(slots=True)
|
|
27
|
+
class AdsbFiMetadata:
|
|
28
|
+
"""Aircraft metadata returned by ADSB.fi."""
|
|
29
|
+
|
|
30
|
+
registration: str | None = None
|
|
31
|
+
aircraft_type: str | None = None
|
|
32
|
+
icao_type: str | None = None
|
|
33
|
+
manufacturer: str | None = None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class AdsbFiMetadataProvider:
|
|
37
|
+
"""
|
|
38
|
+
Retrieve aircraft metadata from ADSB.fi.
|
|
39
|
+
|
|
40
|
+
ADSB.fi is used as a metadata fallback when the
|
|
41
|
+
primary metadata providers do not have sufficient
|
|
42
|
+
information.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def __init__(
|
|
46
|
+
self,
|
|
47
|
+
timeout: float = 10.0,
|
|
48
|
+
) -> None:
|
|
49
|
+
"""Initialize the provider."""
|
|
50
|
+
|
|
51
|
+
self.timeout = timeout
|
|
52
|
+
|
|
53
|
+
def get(
|
|
54
|
+
self,
|
|
55
|
+
icao24: str | None = None,
|
|
56
|
+
) -> AdsbFiMetadata | None:
|
|
57
|
+
"""
|
|
58
|
+
Retrieve aircraft metadata using ICAO24.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
if not icao24:
|
|
62
|
+
return None
|
|
63
|
+
|
|
64
|
+
icao24 = icao24.strip().lower()
|
|
65
|
+
|
|
66
|
+
if not icao24:
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
url = ADSBFI_AIRCRAFT_URL.format(
|
|
70
|
+
icao24=icao24,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
return self._request(url)
|
|
74
|
+
|
|
75
|
+
def _request(
|
|
76
|
+
self,
|
|
77
|
+
url: str,
|
|
78
|
+
) -> AdsbFiMetadata | None:
|
|
79
|
+
"""Request and parse an ADSB.fi response."""
|
|
80
|
+
|
|
81
|
+
try:
|
|
82
|
+
response = requests.get(
|
|
83
|
+
url,
|
|
84
|
+
headers={
|
|
85
|
+
"User-Agent": ADSBFI_USER_AGENT,
|
|
86
|
+
},
|
|
87
|
+
timeout=self.timeout,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
except requests.exceptions.Timeout:
|
|
91
|
+
_LOGGER.debug(
|
|
92
|
+
"ADSB.fi request timed out: %s",
|
|
93
|
+
url,
|
|
94
|
+
)
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
except requests.exceptions.ConnectionError:
|
|
98
|
+
_LOGGER.debug(
|
|
99
|
+
"Unable to connect to ADSB.fi: %s",
|
|
100
|
+
url,
|
|
101
|
+
)
|
|
102
|
+
return None
|
|
103
|
+
|
|
104
|
+
except requests.exceptions.RequestException as exc:
|
|
105
|
+
_LOGGER.debug(
|
|
106
|
+
"ADSB.fi request failed: %s",
|
|
107
|
+
exc,
|
|
108
|
+
)
|
|
109
|
+
return None
|
|
110
|
+
|
|
111
|
+
if response.status_code != 200:
|
|
112
|
+
_LOGGER.debug(
|
|
113
|
+
"ADSB.fi returned HTTP %s",
|
|
114
|
+
response.status_code,
|
|
115
|
+
)
|
|
116
|
+
return None
|
|
117
|
+
|
|
118
|
+
try:
|
|
119
|
+
data = response.json()
|
|
120
|
+
|
|
121
|
+
except ValueError:
|
|
122
|
+
_LOGGER.debug(
|
|
123
|
+
"ADSB.fi returned invalid JSON"
|
|
124
|
+
)
|
|
125
|
+
return None
|
|
126
|
+
|
|
127
|
+
if not isinstance(data, dict):
|
|
128
|
+
return None
|
|
129
|
+
|
|
130
|
+
aircraft = data.get("ac")
|
|
131
|
+
|
|
132
|
+
if not isinstance(aircraft, list):
|
|
133
|
+
return None
|
|
134
|
+
|
|
135
|
+
if not aircraft:
|
|
136
|
+
return None
|
|
137
|
+
|
|
138
|
+
first_aircraft = aircraft[0]
|
|
139
|
+
|
|
140
|
+
if not isinstance(
|
|
141
|
+
first_aircraft,
|
|
142
|
+
dict,
|
|
143
|
+
):
|
|
144
|
+
return None
|
|
145
|
+
|
|
146
|
+
return AdsbFiMetadata(
|
|
147
|
+
registration=self._string(
|
|
148
|
+
first_aircraft.get("r")
|
|
149
|
+
),
|
|
150
|
+
aircraft_type=self._string(
|
|
151
|
+
first_aircraft.get("desc")
|
|
152
|
+
),
|
|
153
|
+
icao_type=self._string(
|
|
154
|
+
first_aircraft.get("t")
|
|
155
|
+
),
|
|
156
|
+
manufacturer=None,
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
@staticmethod
|
|
160
|
+
def _string(
|
|
161
|
+
value: object,
|
|
162
|
+
) -> str | None:
|
|
163
|
+
"""Return a cleaned string or None."""
|
|
164
|
+
|
|
165
|
+
if not isinstance(
|
|
166
|
+
value,
|
|
167
|
+
str,
|
|
168
|
+
):
|
|
169
|
+
return None
|
|
170
|
+
|
|
171
|
+
value = value.strip()
|
|
172
|
+
|
|
173
|
+
if not value:
|
|
174
|
+
return None
|
|
175
|
+
|
|
176
|
+
return value
|