dronecot 2.2.5__tar.gz → 2.3.1__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.
Files changed (41) hide show
  1. dronecot-2.3.1/CHANGELOG.md +180 -0
  2. {dronecot-2.2.5/dronecot.egg-info → dronecot-2.3.1}/PKG-INFO +1 -1
  3. {dronecot-2.2.5 → dronecot-2.3.1/dronecot.egg-info}/PKG-INFO +1 -1
  4. {dronecot-2.2.5 → dronecot-2.3.1}/dronecot.egg-info/SOURCES.txt +4 -0
  5. dronecot-2.3.1/src/dronecot/VERSION +1 -0
  6. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/__init__.py +6 -0
  7. dronecot-2.3.1/src/dronecot/bluez_capture.py +521 -0
  8. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/classes.py +101 -7
  9. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/constants.py +11 -0
  10. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/functions.py +104 -13
  11. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/odid.py +18 -14
  12. dronecot-2.3.1/src/dronecot/rid_track.py +251 -0
  13. dronecot-2.3.1/tests/test_bluez_capture.py +264 -0
  14. {dronecot-2.2.5 → dronecot-2.3.1}/tests/test_functions.py +20 -8
  15. dronecot-2.3.1/tests/test_rid_track.py +401 -0
  16. dronecot-2.2.5/CHANGELOG.md +0 -94
  17. dronecot-2.2.5/src/dronecot/VERSION +0 -1
  18. {dronecot-2.2.5 → dronecot-2.3.1}/LICENSE +0 -0
  19. {dronecot-2.2.5 → dronecot-2.3.1}/MANIFEST.in +0 -0
  20. {dronecot-2.2.5 → dronecot-2.3.1}/README.md +0 -0
  21. {dronecot-2.2.5 → dronecot-2.3.1}/dronecot.egg-info/dependency_links.txt +0 -0
  22. {dronecot-2.2.5 → dronecot-2.3.1}/dronecot.egg-info/entry_points.txt +0 -0
  23. {dronecot-2.2.5 → dronecot-2.3.1}/dronecot.egg-info/requires.txt +0 -0
  24. {dronecot-2.2.5 → dronecot-2.3.1}/dronecot.egg-info/top_level.txt +0 -0
  25. {dronecot-2.2.5 → dronecot-2.3.1}/setup.cfg +0 -0
  26. {dronecot-2.2.5 → dronecot-2.3.1}/setup.py +0 -0
  27. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/ble_capture.py +0 -0
  28. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/ble_parse.py +0 -0
  29. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/commands.py +0 -0
  30. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/dji_exceptions.py +0 -0
  31. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/dji_functions.py +0 -0
  32. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/dji_text_parser.py +0 -0
  33. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/open_drone_id.py +0 -0
  34. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/rid_normalize.py +0 -0
  35. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/udp_rid.py +0 -0
  36. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/wifi_capture.py +0 -0
  37. {dronecot-2.2.5 → dronecot-2.3.1}/src/dronecot/wifi_parse.py +0 -0
  38. {dronecot-2.2.5 → dronecot-2.3.1}/tests/test_adsb_vehicle.py +0 -0
  39. {dronecot-2.2.5 → dronecot-2.3.1}/tests/test_rid_normalize.py +0 -0
  40. {dronecot-2.2.5 → dronecot-2.3.1}/tests/test_sensor_detail.py +0 -0
  41. {dronecot-2.2.5 → dronecot-2.3.1}/tests/test_wifi_parse.py +0 -0
@@ -0,0 +1,180 @@
1
+ ## DroneCOT 2.3.1
2
+
3
+ - **Fix: CoT `ce`/`le` reported ODID accuracy ENUM CODES as if they were metres.**
4
+ ASTM F3411 accuracy fields are enum codes; CoT `<point ce= le=>` are metres.
5
+ Emitting the raw code claimed precision the aircraft never reported, and the
6
+ worst case inverted the meaning entirely: code `0` means *"unknown / >= 18.52
7
+ km"* but rendered as `ce="0"` — a perfect fix. Observed live on a DroneBeacon
8
+ DB120: `HorizAccuracy=9` (ODID *< 30 m*) was drawn on the map at **9 m**, and
9
+ `BaroAccuracy=0` (unknown) as **zero error**. Codes now decode to metres via
10
+ tables mirroring `decodeHorizontalAccuracy()`/`decodeVerticalAccuracy()` in
11
+ opendroneid-core-c; unknown and reserved codes emit the CoT unknown sentinel
12
+ rather than a fabricated number. Four existing tests asserted the old raw
13
+ codes and have been corrected.
14
+ - **Fix: absent altitude rendered as sea level.** `<height value>` defaulted to
15
+ `0`; an unknown altitude now uses the CoT unknown sentinel like `hae`/`ce`/`le`.
16
+ - **Fix: MAC-less feeds shared one placeholder UID.** Serial/MAVLink receivers
17
+ (DroneScout Bridge, SiK) report no MAC, so a Location- or System-only message
18
+ had neither MAC nor serial and rendered as `Unknown-BasicID_0`, colliding
19
+ across every such source. The UID now falls back to `FEED-<sensor_id>`.
20
+ Measured on a live DroneScout Bridge: 57 correctly identified events alongside
21
+ 3 placeholders. Aggregation is deliberately NOT keyed on the feed — one
22
+ receiver reports many aircraft, so that would merge distinct drones.
23
+
24
+ ## DroneCOT 2.3.0
25
+
26
+ Correctness release for single-message Remote ID. A BLE legacy transmitter fits
27
+ only ONE 25-byte ODID message per advertisement and rotates through message
28
+ types, so the serial, the UAS position and the operator location arrive in
29
+ *different* frames. DroneCOT rendered each frame independently, which broke
30
+ badly in the field.
31
+
32
+ - **Fix: CoT XML could contain NUL bytes and fail to parse.** ODID pads its
33
+ fixed-width ASCII fields (20-byte serial, 23-byte text) with NUL, and
34
+ `clean_SN()` / `clean_string()` stripped only whitespace. Any UAS whose serial
35
+ was shorter than the field emitted a CoT UID such as
36
+ `RID.SHORTSN\0\0\0....uas` — 82 NUL bytes in the document, which is illegal in
37
+ XML 1.0 and will not reparse. Both cleaners now strip NUL and all C0 control
38
+ characters. Affected every source (Wi-Fi, BLE, serial, MQTT); went unnoticed
39
+ because every committed fixture uses a full-width 20-character serial.
40
+ - **Fix: every drone collapsed onto one track.** A Location message carries a
41
+ position but no serial, so it rendered with the constant UID
42
+ `RID.Unknown-BasicID_0.uas` — all aircraft in range shared one track. The UID
43
+ now falls back to the advertiser MAC (`MAC-<addr>`) so distinct transmitters
44
+ stay distinct.
45
+ - **Fix: BasicID and System messages were silently dropped**, having no position
46
+ of their own.
47
+ - **New `rid_track.ODIDAggregator`**: merges successive single ODID messages per
48
+ transmitter (keyed on the advertiser MAC, which ASTM F3411 requires to be
49
+ stable for a flight session) so a CoT carries the serial from one
50
+ advertisement and the position from another. TTL-expired and hard-capped to
51
+ bound memory. Wired into `RIDWorker.handle_data()`, the single choke point all
52
+ workers feed, so Wi-Fi, BLE, serial, MQTT and UDP all benefit. Full `0xF`
53
+ message packs are unaffected — they already carry everything in one frame.
54
+ Tunable via `RID_TRACK_TTL` (default 120 s; set 0 to disable),
55
+ `RID_TRACK_MAX` (default 512) and `RID_TRACK_ID_GRACE` (default 5 s).
56
+ `RID_TRACK_ID_GRACE` briefly holds a position-only track while waiting for
57
+ its serial, so one aircraft does not appear as two TAK markers (first under a
58
+ MAC-derived UID, then under the real serial); after the grace period an
59
+ unidentified drone renders anyway.
60
+
61
+ **Measured against a live BlueMark DroneBeacon DB120** over 234 real BLE
62
+ advertisements: without aggregation only 57 (24%) rendered as CoT and the
63
+ real serial NEVER appeared — every event used the MAC fallback UID. With
64
+ aggregation 230 (98%) rendered, all under the correct serial
65
+ `RID.1787F04BM24010011195.uas`. The transmitter sent BasicID, Location and
66
+ System as separate advertisements and no `0xF` message packs at all,
67
+ confirming the single-message rotation this release exists to handle.
68
+ - **Fix: operator CoT UID ignored the MAC.** `rid_op_to_cot_xml()` read
69
+ `data["MAC address"]`, but wireless captures put it in `data["data"]`, so the
70
+ Drone-Hone-style `op-<mac>` UID never actually used a MAC.
71
+ - Replace deprecated `datetime.utcfromtimestamp()` (Python 3.12+ warning).
72
+ - Tests: 16 new, including a real ASTM F3411 advertisement captured off the air
73
+ from a BlueMark DroneBeacon DB120 — the existing fixtures are all message
74
+ packs or CUAS blobs and never exercised the single-message path.
75
+
76
+ ## DroneCOT 2.2.5
77
+
78
+ - Enrich RID CoT `<__cuas>` detail and remarks with `sensor_model`,
79
+ `sensor_method` and `band`. New `SENSOR_MODEL` / `SENSOR_TYPE` config.
80
+
81
+ ## DroneCOT 2.2.4
82
+
83
+ - `wifi_parse`: fix `extract_odid_from_scapy_packet()`, which decoded zero
84
+ beacons because `bytes(elt.oui)` on an int produced a 16 MB zero buffer. Now
85
+ delegates to `extract_odid_from_dot11(bytes(dot11))`.
86
+
87
+ ## DroneCOT 2.2.3
88
+
89
+ - SerialWorker: handle MAVLink **ADSB_VEHICLE** messages (in addition to
90
+ OPEN_DRONE_ID_MESSAGE_PACK), so Remote ID receivers that emit ADS-B-style
91
+ frames — e.g. the **BlueMark DroneScout Bridge (DS101)** in ADS-B output mode
92
+ — are decoded to CoT. Adds a test for the ADSB_VEHICLE -> RID conversion.
93
+
94
+ ## DroneCOT 2.2.2
95
+
96
+ - Fix UTC timestamp handling on Python 3.9 and 3.10.
97
+
98
+ ## DroneCOT 2.2.1
99
+
100
+ - Use PyTAK shared CoT event, point, detail, remarks, and serialization helpers.
101
+ - Replace `pytz` timestamp handling with standard-library timezone handling.
102
+ - Require `pytak >= 7.3.12`.
103
+
104
+ ## DroneCOT 2.2.0
105
+
106
+ - Add `SensorWorker`: periodic `a-f-G-E-S-E` sensor CoT heartbeat, emitted every `SENSOR_KEEPALIVE_PERIOD` seconds (default 30).
107
+ - Position sourced from system gpsd if present (mode 2/3 fix); falls back to static `SENSOR_LAT`/`SENSOR_LON`/`SENSOR_HAE` config; falls back to null island (0, 0, 0).
108
+ - Add `gen_sensor_cot()`: reusable CoT generator for sensor beacon events, used by `SensorWorker`.
109
+ - New constants: `DEFAULT_SENSOR_KEEPALIVE_PERIOD = 30`, `DEFAULT_SENSOR_LAT/LON/HAE = 0.0`.
110
+ - Add `gpsd-py3` as optional runtime dependency (soft import, gracefully absent).
111
+
112
+ ## DroneCOT 2.1.5
113
+
114
+ - Add `takproto` to postinst pip install; enables TAK Protocol v1 protobuf encoding over WebSocket when connected to TAK Server via `wss://`.
115
+
116
+ ## DroneCOT 2.1.4
117
+
118
+ - Fix packaging: `postinst` now installs `aiomqtt` and `pymavlink` via pip for Debian systems where these packages are not yet available in the distro repos.
119
+
120
+ ## DroneCOT 2.1.3
121
+
122
+ - Fix: make `aiomqtt` a conditional import so the package loads without it when MQTT is not used; `MQTTWorker` raises `ImportError` with a helpful message if aiomqtt is missing at runtime.
123
+
124
+ ## DroneCOT 2.1.2
125
+
126
+ - Fix: `DJI_TCP_PORT` and `UDP_RID_PORT` config keys now take precedence over `FEED_URL` in `create_tasks` routing, eliminating the need to set `FEED_URL=` when using the DJI listener or UDP Remote ID worker without an explicit feed URL.
127
+
128
+ ## DroneCOT 2.1.1
129
+
130
+ - Fix: `DJIWorker` argument order in `create_tasks` (`net_queue` and `config` were swapped in all three call sites).
131
+
132
+ ## DroneCOT 2.1.0
133
+
134
+ - Add `UDPRIDWorker`: UDP listener (default port 9999) for pre-decoded Wi-Fi / BLE Remote ID JSON broadcasts from drone detection nodes.
135
+ - Add `udp_rid.py` module: `parse_udp_rid_message()` and `parse_udp_rid_line()` convert flat decoded JSONL (`t`, `mac`, `radio`, `rssi`, `lat`, `lon`, `alt`, `speed`, `hdg`, `id`) to RIDWorker-compatible dicts.
136
+ - Map `radio` field values (`wifi_beacon`, `wifi_nan`, `ble_legacy`, `ble_long_range`, `ble_coded`) to sensor type labels used by CoT generator.
137
+ - `create_tasks` now routes `udp://` feed URL or `UDP_RID_PORT` config option to `UDPRIDWorker` + `RIDWorker`.
138
+ - Fix: `wifi://`, `ble://`, `wireless://` branches now correctly include `RIDWorker` to consume the net_queue they produce.
139
+ - New constants: `DEFAULT_UDP_RID_PORT = 9999`, `DEFAULT_UDP_RID_HOST = "0.0.0.0"`.
140
+
141
+ ## DroneCOT 2.0.0
142
+
143
+ - Absorbed DJI Drone ID (DJICOT) support directly into dronecot package.
144
+ - Added `DJIWorker`, `DJINetWorker`, `DJITextWorker`, `DJIFileWorker`, `DJIListenerWorker` for AntSDR binary and text CSV feeds.
145
+ - Added `gen_dji_cot`, `dji_uas_to_cot`, `dji_op_to_cot`, `dji_home_to_cot`, `dji_sensor_to_cot` CoT generators.
146
+ - Added `dji_handle_frame`, `dji_handle_text_line`, `dji_handle_parsed_data` feed handlers.
147
+ - Added `dji_functions.py` (binary frame parser) and `dji_text_parser.py` (AntSDR CSV parser).
148
+ - Added `dji_exceptions.py`: `DJICOTError`, `DJIDataError`, `DJIConnectionError`, `DJIConfigurationError`.
149
+ - `create_tasks` now routes `tcp://` → DJI binary/text, `file://` → DJI replay, `DJI_TCP_PORT` set → DJI listener.
150
+ - Added DJI constants: `DEFAULT_DJI_FEED_URL`, `DEFAULT_DJI_TEXT_FEED_URL`, `DEFAULT_DJI_*_PORT`, etc.
151
+ - Backward-compat aliases: `NetWorker`, `BinaryNetWorker`, `TextNetWorker`, `FileReplayWorker`, `TCPListenerWorker`.
152
+
153
+ ## DroneCOT 1.2.0
154
+
155
+ - Add native Linux wireless Remote ID capture: Wi-Fi monitor mode (Beacon + NAN)
156
+ and BLE via Sniffle-compatible dongle (`wifi://`, `ble://`, `wireless://` feeds).
157
+ - Add `rid_normalize`, `wifi_parse`, `wifi_capture`, `ble_parse`, and `ble_capture`
158
+ modules; optional `pip install 'dronecot[wireless]'` for Scapy.
159
+
160
+ ## DroneCOT 1.1.3
161
+
162
+ - Add user-systemd instance template (`dronecot@.service`) to support running
163
+ serial and MQTT DroneCOT workers side-by-side with layered defaults files.
164
+
165
+ ## DroneCOT 1.1.2
166
+
167
+ - Unfixes #2.
168
+
169
+ ## DroneCOT 1.1.1
170
+
171
+ - Fixes #2: Missing cot_to_xml function export.
172
+
173
+ ## DroneCOT 1.1.0
174
+
175
+ * Updates
176
+
177
+
178
+ ## DroneCOT 1.0.0
179
+
180
+ Initial release of DroneCOT.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dronecot
3
- Version: 2.2.5
3
+ Version: 2.3.1
4
4
  Summary: Display Drones in Team Awareness Kit (TAK).
5
5
  Home-page: https://github.com/snstac/dronecot
6
6
  Maintainer: Greg Albrecht <oss@undef.net>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dronecot
3
- Version: 2.2.5
3
+ Version: 2.3.1
4
4
  Summary: Display Drones in Team Awareness Kit (TAK).
5
5
  Home-page: https://github.com/snstac/dronecot
6
6
  Maintainer: Greg Albrecht <oss@undef.net>
@@ -14,6 +14,7 @@ src/dronecot/VERSION
14
14
  src/dronecot/__init__.py
15
15
  src/dronecot/ble_capture.py
16
16
  src/dronecot/ble_parse.py
17
+ src/dronecot/bluez_capture.py
17
18
  src/dronecot/classes.py
18
19
  src/dronecot/commands.py
19
20
  src/dronecot/constants.py
@@ -24,11 +25,14 @@ src/dronecot/functions.py
24
25
  src/dronecot/odid.py
25
26
  src/dronecot/open_drone_id.py
26
27
  src/dronecot/rid_normalize.py
28
+ src/dronecot/rid_track.py
27
29
  src/dronecot/udp_rid.py
28
30
  src/dronecot/wifi_capture.py
29
31
  src/dronecot/wifi_parse.py
30
32
  tests/test_adsb_vehicle.py
33
+ tests/test_bluez_capture.py
31
34
  tests/test_functions.py
32
35
  tests/test_rid_normalize.py
36
+ tests/test_rid_track.py
33
37
  tests/test_sensor_detail.py
34
38
  tests/test_wifi_parse.py
@@ -0,0 +1 @@
1
+ 2.3.1
@@ -38,6 +38,10 @@ from .constants import ( # NOQA
38
38
  DEFAULT_OP_COT_TYPE,
39
39
  DEFAULT_HOME_COT_TYPE,
40
40
  DEFAULT_UAS_COT_TYPE,
41
+ # Per-transmitter RID track aggregation constants
42
+ DEFAULT_RID_TRACK_TTL,
43
+ DEFAULT_RID_TRACK_MAX,
44
+ DEFAULT_RID_TRACK_ID_GRACE,
41
45
  # UDP pre-decoded Remote ID constants
42
46
  DEFAULT_UDP_RID_PORT,
43
47
  DEFAULT_UDP_RID_HOST,
@@ -86,6 +90,7 @@ from .udp_rid import ( # NOQA
86
90
 
87
91
  from .classes import ( # NOQA
88
92
  BleWorker,
93
+ BlueZWorker,
89
94
  MQTTWorker,
90
95
  RIDWorker,
91
96
  RXMockWorker,
@@ -117,6 +122,7 @@ from .dji_exceptions import ( # NOQA
117
122
 
118
123
  from . import odid # NOQA
119
124
  from . import rid_normalize # NOQA
125
+ from . import rid_track # NOQA
120
126
 
121
127
  from .open_drone_id import (
122
128
  ODIDValidBlocks,