sp-rtk-base-relay 2.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.
- sp_rtk_base_relay-2.1.0/PKG-INFO +405 -0
- sp_rtk_base_relay-2.1.0/README.md +367 -0
- sp_rtk_base_relay-2.1.0/pyproject.toml +202 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/__init__.py +26 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/config.py +1274 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/__init__.py +13 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/bluetooth_manager.py +744 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/broadcast_hub.py +719 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/connection_states.py +60 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/data_pipeline.py +583 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/destinations/__init__.py +43 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/destinations/base_destination.py +378 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/destinations/destination_factory.py +204 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/destinations/ntrip_destination.py +416 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/destinations/surepath_destination.py +223 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/destinations/tcp_server_destination.py +378 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/events.py +485 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/input_sources/__init__.py +21 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/input_sources/base_input.py +184 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/input_sources/bluetooth_input.py +333 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/input_sources/input_factory.py +417 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/input_sources/serial_input.py +360 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/input_sources/tcp_input.py +405 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/message_filter.py +222 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/rtcm_client.py +555 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/core/status.py +270 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/engine.py +356 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/exceptions.py +340 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/logger.py +503 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/main.py +464 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/metrics.py +780 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/py.typed +0 -0
- sp_rtk_base_relay-2.1.0/src/sp_rtk_base_relay/rtcm_decoder.py +532 -0
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: sp-rtk-base-relay
|
|
3
|
+
Version: 2.1.0
|
|
4
|
+
Summary: RTCM relay service for custom GPS correction servers
|
|
5
|
+
Keywords: rtcm,gps,gnss,rtk,base-station,corrections
|
|
6
|
+
Author: John Roden
|
|
7
|
+
Author-email: John Roden <rodenj@gmail.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
18
|
+
Classifier: Topic :: System :: Networking
|
|
19
|
+
Requires-Dist: pyserial>=3.5
|
|
20
|
+
Requires-Dist: pyyaml>=6.0
|
|
21
|
+
Requires-Dist: prometheus-client>=0.17.0
|
|
22
|
+
Requires-Dist: dbus-fast>=2.0.0
|
|
23
|
+
Requires-Dist: pytest>=7.0.0 ; extra == 'dev'
|
|
24
|
+
Requires-Dist: pytest-cov>=4.0.0 ; extra == 'dev'
|
|
25
|
+
Requires-Dist: pytest-asyncio>=0.21.0 ; extra == 'dev'
|
|
26
|
+
Requires-Dist: mypy>=1.5.0 ; extra == 'dev'
|
|
27
|
+
Requires-Dist: types-pyyaml ; extra == 'dev'
|
|
28
|
+
Requires-Dist: ruff>=0.6.0 ; extra == 'dev'
|
|
29
|
+
Requires-Dist: pylint>=2.17.0 ; extra == 'dev'
|
|
30
|
+
Requires-Dist: pre-commit>=3.0.0 ; extra == 'dev'
|
|
31
|
+
Requires-Python: >=3.10
|
|
32
|
+
Project-URL: Homepage, https://github.com/rodenj1/sp-rtk-base-relay
|
|
33
|
+
Project-URL: Documentation, https://github.com/rodenj1/sp-rtk-base-relay#readme
|
|
34
|
+
Project-URL: Repository, https://github.com/rodenj1/sp-rtk-base-relay
|
|
35
|
+
Project-URL: Issues, https://github.com/rodenj1/sp-rtk-base-relay/issues
|
|
36
|
+
Provides-Extra: dev
|
|
37
|
+
Description-Content-Type: text/markdown
|
|
38
|
+
|
|
39
|
+
# SP-RTK-Base-Relay
|
|
40
|
+
|
|
41
|
+
A Python service that relays RTCM correction data from RTK GPS base stations to **multiple destinations** simultaneously โ Sure-Path servers, NTRIP casters, and local TCP clients.
|
|
42
|
+
|
|
43
|
+
[](https://github.com/rodenj1/sp-rtk-base-relay/actions/workflows/ci.yml)
|
|
44
|
+
[](https://github.com/rodenj1/sp-rtk-base-relay/actions/workflows/release.yml)
|
|
45
|
+
[](https://codecov.io/gh/rodenj1/sp-rtk-base-relay)
|
|
46
|
+
[](https://pypi.org/project/sp-rtk-base-relay/)
|
|
47
|
+
[](https://pypi.org/project/sp-rtk-base-relay/)
|
|
48
|
+
[](https://pypi.org/project/sp-rtk-base-relay/)
|
|
49
|
+
[](LICENSE)
|
|
50
|
+
[](https://github.com/astral-sh/ruff)
|
|
51
|
+
|
|
52
|
+
## Overview
|
|
53
|
+
|
|
54
|
+
SP-Base-Relay v2.1 is a production-ready multi-destination RTCM relay and **embeddable Python library**. A single GPS input source (TCP, serial, or Bluetooth) feeds correction data to any combination of destinations โ proprietary Sure-Path servers, NTRIP v1.0/v2.0 casters (RTK2go, Onocoy, rtkdirect), and local TCP rebroadcast servers.
|
|
55
|
+
|
|
56
|
+
### Key Features
|
|
57
|
+
|
|
58
|
+
- ๐ **Multi-Destination Broadcast**: Fan-out RTCM data to 1โN destinations simultaneously
|
|
59
|
+
- ๐ **NTRIP v1.0 + v2.0**: Push corrections to any NTRIP caster (RTK2go, Onocoy, rtkdirect)
|
|
60
|
+
- ๐ก **TCP Rebroadcast Server**: Serve corrections to LAN rovers via TCP
|
|
61
|
+
- ๐ **Sure-Path Protocol**: Custom `INIT:user:pass*` auth with `$HB$` heartbeat monitoring
|
|
62
|
+
- ๐ **Multiple Input Sources**: TCP (RTKBase), Serial UART, USB Serial, Bluetooth GPS
|
|
63
|
+
- ๐ฏ **Per-Destination Filtering**: Pass-all, allowlist, or blocklist RTCM message types per destination
|
|
64
|
+
- ๐ **Per-Destination Prometheus Metrics**: Individual throughput, errors, queue depth per destination
|
|
65
|
+
- ๐ **Automatic Recovery**: Exponential backoff reconnection per destination โ independent fault isolation
|
|
66
|
+
- ๐ง **Self-Healing Bluetooth**: Automatic Bluetooth GPS recovery without manual intervention
|
|
67
|
+
- ๐ก๏ธ **Production Ready**: Systemd integration, structured logging, comprehensive error handling
|
|
68
|
+
- ๐งช **Well Tested**: 88% code coverage with 1,106 passing tests
|
|
69
|
+
- ๐งฉ **Embeddable Library** (v2.1): `RelayEngine` API for programmatic control by external applications
|
|
70
|
+
- ๐ข **Real-Time Events** (v2.1): EventBus with typed events for state change notifications
|
|
71
|
+
- ๐ **Hot Plug Destinations** (v2.1): Add/remove/start/stop destinations while running
|
|
72
|
+
|
|
73
|
+
## Architecture
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
โโโโถ [SurePath Thread] โโโถ Sure-Path Server
|
|
77
|
+
[Input Source] โโโถ [BroadcastHub] โโคโโโถ [NTRIP Thread] โโโถ RTK2go / Onocoy / etc.
|
|
78
|
+
TCP / Serial Fan-out โโโโถ [NTRIP Thread] โโโถ rtkdirect
|
|
79
|
+
/ Bluetooth + Filter โโโโถ [TCP Srv Thread] โโโถ LAN Rover Clients
|
|
80
|
+
โ
|
|
81
|
+
[Prometheus Metrics] โโโโโ per-destination labels
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Each destination runs in its own thread with an independent queue, so a failure in one destination never affects the others.
|
|
85
|
+
|
|
86
|
+
## Quick Start
|
|
87
|
+
|
|
88
|
+
### Installation
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
git clone https://github.com/rodenj1/sp-rtk-base-relay.git
|
|
92
|
+
cd sp-rtk-base-relay
|
|
93
|
+
sudo ./tools/install.sh
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Configuration
|
|
97
|
+
|
|
98
|
+
Edit `/etc/sp-rtk-base-relay/config.yaml` (or see `config.example.yaml`):
|
|
99
|
+
|
|
100
|
+
```yaml
|
|
101
|
+
input:
|
|
102
|
+
source: "tcp"
|
|
103
|
+
config:
|
|
104
|
+
host: "192.168.1.100"
|
|
105
|
+
port: 3000
|
|
106
|
+
|
|
107
|
+
destinations:
|
|
108
|
+
- name: surepath
|
|
109
|
+
type: surepath
|
|
110
|
+
enabled: true
|
|
111
|
+
filter:
|
|
112
|
+
mode: pass_all
|
|
113
|
+
config:
|
|
114
|
+
host: "server.example.com"
|
|
115
|
+
port: 50010
|
|
116
|
+
username: "USER01"
|
|
117
|
+
password: "abc1"
|
|
118
|
+
|
|
119
|
+
- name: rtk2go
|
|
120
|
+
type: ntrip
|
|
121
|
+
enabled: true
|
|
122
|
+
filter:
|
|
123
|
+
mode: pass_all
|
|
124
|
+
config:
|
|
125
|
+
caster: "rtk2go.com"
|
|
126
|
+
port: 2101
|
|
127
|
+
mountpoint: "MY_MOUNT"
|
|
128
|
+
password: "my_password"
|
|
129
|
+
version: "2.0"
|
|
130
|
+
|
|
131
|
+
- name: local_tcp
|
|
132
|
+
type: tcp_server
|
|
133
|
+
enabled: false
|
|
134
|
+
filter:
|
|
135
|
+
mode: pass_all
|
|
136
|
+
config:
|
|
137
|
+
host: "0.0.0.0"
|
|
138
|
+
port: 5016
|
|
139
|
+
max_clients: 10
|
|
140
|
+
|
|
141
|
+
metrics:
|
|
142
|
+
enabled: true
|
|
143
|
+
port: 8080
|
|
144
|
+
|
|
145
|
+
logging:
|
|
146
|
+
level: "INFO"
|
|
147
|
+
format: "json"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Running
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# As a systemd service
|
|
154
|
+
sudo systemctl start sp-rtk-base-relay
|
|
155
|
+
|
|
156
|
+
# Or foreground
|
|
157
|
+
sp-rtk-base-relay --config config.yaml --foreground
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Destination Types
|
|
161
|
+
|
|
162
|
+
### Sure-Path (`surepath`)
|
|
163
|
+
Custom proprietary protocol with `INIT:user:pass*` authentication and `$HB$` heartbeat monitoring. Wraps the battle-tested v1.x RTCMClient.
|
|
164
|
+
|
|
165
|
+
### NTRIP (`ntrip`)
|
|
166
|
+
Pushes RTCM corrections to NTRIP casters. Supports both protocol versions:
|
|
167
|
+
- **v2.0** (default): HTTP POST + Basic auth + chunked transfer encoding
|
|
168
|
+
- **v1.0**: SOURCE auth + raw binary streaming
|
|
169
|
+
|
|
170
|
+
Tested against RTK2go, Onocoy, and rtkdirect.
|
|
171
|
+
|
|
172
|
+
### TCP Server (`tcp_server`)
|
|
173
|
+
Local TCP rebroadcast server for LAN clients. Multiple rovers can connect and receive corrections simultaneously. Features max_clients enforcement and per-client write timeout for backpressure handling.
|
|
174
|
+
|
|
175
|
+
## Message Filtering
|
|
176
|
+
|
|
177
|
+
Each destination can independently filter RTCM messages by type ID:
|
|
178
|
+
|
|
179
|
+
```yaml
|
|
180
|
+
filter:
|
|
181
|
+
mode: pass_all # Forward everything (zero overhead)
|
|
182
|
+
|
|
183
|
+
filter:
|
|
184
|
+
mode: allowlist # Only forward these message types
|
|
185
|
+
message_ids: [1005, 1077, 1087, 1097, 1127]
|
|
186
|
+
|
|
187
|
+
filter:
|
|
188
|
+
mode: blocklist # Forward everything except these
|
|
189
|
+
message_ids: [4072] # Drop proprietary messages
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Monitoring
|
|
193
|
+
|
|
194
|
+
### Prometheus Metrics
|
|
195
|
+
|
|
196
|
+
Per-destination metrics with `{destination="..."}` labels:
|
|
197
|
+
|
|
198
|
+
| Metric | Type | Description |
|
|
199
|
+
|--------|------|-------------|
|
|
200
|
+
| `sp_rtk_base_relay_dest_bytes_sent_total` | Counter | Bytes sent per destination |
|
|
201
|
+
| `sp_rtk_base_relay_dest_messages_sent_total` | Counter | Messages sent per destination |
|
|
202
|
+
| `sp_rtk_base_relay_dest_messages_dropped_total` | Counter | Queue overflow drops per destination |
|
|
203
|
+
| `sp_rtk_base_relay_dest_connection_status` | Gauge | Connection state (1/0) per destination |
|
|
204
|
+
| `sp_rtk_base_relay_dest_errors_total` | Counter | Errors per destination |
|
|
205
|
+
| `sp_rtk_base_relay_dest_queue_depth` | Gauge | Queue depth per destination |
|
|
206
|
+
| `sp_rtk_base_relay_input_connection_status` | Gauge | Input source connection state |
|
|
207
|
+
| `sp_rtk_base_relay_input_seconds_since_last_data` | Gauge | No-data watchdog |
|
|
208
|
+
| `sp_rtk_base_relay_tcp_server_connected_clients` | Gauge | TCP server client count |
|
|
209
|
+
| `sp_rtk_base_relay_service_uptime_seconds` | Gauge | Service uptime |
|
|
210
|
+
|
|
211
|
+
### Grafana Dashboard
|
|
212
|
+
|
|
213
|
+
Import `templates/grafana_dashboard.json` for a pre-built v2 dashboard with per-destination panels, throughput graphs, and the no-data watchdog.
|
|
214
|
+
|
|
215
|
+
## Input Sources
|
|
216
|
+
|
|
217
|
+
| Source | Use Case | Config Key |
|
|
218
|
+
|--------|----------|------------|
|
|
219
|
+
| `tcp` | RTKBase integration, network base stations | `host`, `port`, `timeout` |
|
|
220
|
+
| `serial` | Direct GNSS receiver via UART | `port`, `baudrate` |
|
|
221
|
+
| `usb_serial` | USB-to-serial adapters | `port`, `baudrate` |
|
|
222
|
+
| `bluetooth` | Bluetooth GPS devices | `device_address`, `channel` |
|
|
223
|
+
|
|
224
|
+
## Project Structure
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
sp-rtk-base-relay/
|
|
228
|
+
โโโ src/sp_rtk_base_relay/
|
|
229
|
+
โ โโโ main.py # Service orchestration (v2)
|
|
230
|
+
โ โโโ config.py # YAML config with destinations: list
|
|
231
|
+
โ โโโ metrics.py # Per-destination Prometheus metrics
|
|
232
|
+
โ โโโ exceptions.py # DestinationError, NtripError, etc.
|
|
233
|
+
โ โโโ logger.py # Structured logging
|
|
234
|
+
โ โโโ rtcm_decoder.py # RTCM 3.x frame parser
|
|
235
|
+
โ โโโ core/
|
|
236
|
+
โ โโโ broadcast_hub.py # Fan-out coordinator (input โ N queues)
|
|
237
|
+
โ โโโ message_filter.py # Per-destination RTCM filtering
|
|
238
|
+
โ โโโ rtcm_client.py # Sure-Path protocol client
|
|
239
|
+
โ โโโ connection_states.py # Connection state machine
|
|
240
|
+
โ โโโ bluetooth_manager.py # Bluetooth GPS recovery
|
|
241
|
+
โ โโโ destinations/
|
|
242
|
+
โ โ โโโ base_destination.py # ABC + queue + stats
|
|
243
|
+
โ โ โโโ destination_factory.py # Registry-based factory
|
|
244
|
+
โ โ โโโ surepath_destination.py # Sure-Path server
|
|
245
|
+
โ โ โโโ ntrip_destination.py # NTRIP v1.0 + v2.0
|
|
246
|
+
โ โ โโโ tcp_server_destination.py # Async TCP rebroadcast
|
|
247
|
+
โ โโโ input_sources/
|
|
248
|
+
โ โโโ base_input.py # Input ABC
|
|
249
|
+
โ โโโ tcp_input.py # TCP input
|
|
250
|
+
โ โโโ serial_input.py # Serial input
|
|
251
|
+
โ โโโ bluetooth_input.py # Bluetooth input
|
|
252
|
+
โโโ tests/ # 942 tests, 88% coverage
|
|
253
|
+
โ โโโ unit/ # Unit tests (26 test files)
|
|
254
|
+
โ โโโ integration/ # Hardware integration tests
|
|
255
|
+
โ โโโ manual/ # Manual production tests
|
|
256
|
+
โ โโโ fixtures/ # Mock servers and generators
|
|
257
|
+
โโโ tools/ # Install/uninstall, systemd, bluetooth
|
|
258
|
+
โโโ templates/ # Grafana dashboard v2
|
|
259
|
+
โโโ docs/ # Documentation
|
|
260
|
+
โ โโโ v2-architecture-plan.md # Full architecture + design decisions
|
|
261
|
+
โ โโโ deployment-guide.md # Installation & deployment
|
|
262
|
+
โ โโโ metrics-guide.md # Prometheus metrics reference
|
|
263
|
+
โ โโโ bluetooth-*.md # Bluetooth GPS guides
|
|
264
|
+
โโโ config.example.yaml # v2 configuration template
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Development
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
# Clone and install
|
|
271
|
+
git clone https://github.com/rodenj1/sp-rtk-base-relay.git
|
|
272
|
+
cd sp-rtk-base-relay
|
|
273
|
+
uv sync --all-extras
|
|
274
|
+
source .venv/bin/activate
|
|
275
|
+
|
|
276
|
+
# Run tests
|
|
277
|
+
uv run pytest
|
|
278
|
+
|
|
279
|
+
# Run with coverage
|
|
280
|
+
uv run pytest --cov=src/sp_rtk_base_relay --cov-report=html
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Code Quality Standards
|
|
284
|
+
- Python 3.10+ with modern type hints (`dict`, `list`, `X | None`)
|
|
285
|
+
- PEP8 code style, pyright strict mode
|
|
286
|
+
- >88% test coverage (942 tests)
|
|
287
|
+
- UV package management
|
|
288
|
+
|
|
289
|
+
## CLI Usage
|
|
290
|
+
|
|
291
|
+
```
|
|
292
|
+
sp-rtk-base-relay [OPTIONS]
|
|
293
|
+
|
|
294
|
+
Options:
|
|
295
|
+
--version Show version and exit
|
|
296
|
+
-c, --config PATH Configuration file path
|
|
297
|
+
--validate Validate configuration and exit
|
|
298
|
+
--generate-config Generate example configuration
|
|
299
|
+
--foreground Run in foreground
|
|
300
|
+
--log-level LEVEL Override log level
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
## Embedded Usage (v2.1)
|
|
304
|
+
|
|
305
|
+
SP-Base-Relay can be used as a **Python library** by external applications (e.g., GPS configuration UIs). The `RelayEngine` facade provides full programmatic control:
|
|
306
|
+
|
|
307
|
+
```python
|
|
308
|
+
from sp_rtk_base_relay import RelayEngine
|
|
309
|
+
from sp_rtk_base_relay.config import InputConfig, DestinationConfig
|
|
310
|
+
|
|
311
|
+
# 1. Create engine with input source
|
|
312
|
+
engine = RelayEngine(InputConfig(source="tcp", config={"host": "192.168.1.100", "port": 3000}))
|
|
313
|
+
|
|
314
|
+
# 2. Start with destinations
|
|
315
|
+
engine.start([
|
|
316
|
+
DestinationConfig(name="rtk2go", type="ntrip", enabled=True,
|
|
317
|
+
config={"caster": "rtk2go.com", "port": 2101,
|
|
318
|
+
"mountpoint": "MY_MOUNT", "password": "pass"}),
|
|
319
|
+
])
|
|
320
|
+
|
|
321
|
+
# 3. Hot-add a destination while running
|
|
322
|
+
engine.add_destination(DestinationConfig(
|
|
323
|
+
name="local_tcp", type="tcp_server", enabled=True,
|
|
324
|
+
config={"host": "0.0.0.0", "port": 5016}
|
|
325
|
+
))
|
|
326
|
+
|
|
327
|
+
# 4. Get typed status snapshot
|
|
328
|
+
status = engine.get_status()
|
|
329
|
+
print(f"Running: {status.is_running}, Destinations: {len(status.destinations)}")
|
|
330
|
+
|
|
331
|
+
# 5. Subscribe to real-time events
|
|
332
|
+
sub = engine.subscribe_events()
|
|
333
|
+
event = sub.get_event(timeout=1.0)
|
|
334
|
+
if event:
|
|
335
|
+
print(f"Event: {event.event_type} โ {event.message}")
|
|
336
|
+
sub.close()
|
|
337
|
+
|
|
338
|
+
# 6. Stop when done (releases serial port for other tools)
|
|
339
|
+
engine.stop()
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Exported API
|
|
343
|
+
|
|
344
|
+
| Symbol | Description |
|
|
345
|
+
|--------|-------------|
|
|
346
|
+
| `RelayEngine` | High-level facade โ start/stop/manage relay |
|
|
347
|
+
| `EventBus` | Pub/sub event system |
|
|
348
|
+
| `EventSubscription` | Per-subscriber event queue (iterable) |
|
|
349
|
+
| `RelayEvent` | Typed event (event_type, message, timestamp, payload) |
|
|
350
|
+
| `RelayStatus` | Frozen status snapshot |
|
|
351
|
+
| `DestinationStatus` | Per-destination status |
|
|
352
|
+
| `InputStatus` | Input source status |
|
|
353
|
+
|
|
354
|
+
See **[Relay Engine API Spec](docs/relay-engine-api-spec.md)** for the full technical specification.
|
|
355
|
+
|
|
356
|
+
## Migration from v1.x
|
|
357
|
+
|
|
358
|
+
v2.0 is a **breaking change**. Key differences:
|
|
359
|
+
|
|
360
|
+
| v1.x | v2.0 |
|
|
361
|
+
|------|------|
|
|
362
|
+
| `server:` config key | `destinations:` list |
|
|
363
|
+
| Single destination | 1โN destinations |
|
|
364
|
+
| Global metrics | Per-destination `{destination="..."}` labels |
|
|
365
|
+
| `DataPipelineCoordinator` | `BroadcastHub` + `DestinationFactory` |
|
|
366
|
+
| v1 Grafana dashboard | v2 dashboard with `$destination` variable |
|
|
367
|
+
|
|
368
|
+
See `config.example.yaml` for the new format. Old `server:` configs are detected with a clear migration error message.
|
|
369
|
+
|
|
370
|
+
## Releasing
|
|
371
|
+
|
|
372
|
+
Releases to PyPI are fully automated via `.github/workflows/release.yml`.
|
|
373
|
+
Bump the version in `pyproject.toml`, push a `vX.Y.Z` tag, then publish a
|
|
374
|
+
GitHub Release โ the workflow re-runs the full test matrix, builds, and
|
|
375
|
+
publishes to PyPI via Trusted Publishing (OIDC, no API tokens). See
|
|
376
|
+
**[docs/release-process.md](docs/release-process.md)** for the per-release
|
|
377
|
+
checklist and the one-time PyPI / GitHub-environment setup.
|
|
378
|
+
|
|
379
|
+
## Documentation
|
|
380
|
+
|
|
381
|
+
- **[Release Process](docs/release-process.md)**: PyPI release workflow + runbook
|
|
382
|
+
- **[Relay Engine API Spec](docs/relay-engine-api-spec.md)**: Full v2.1 programmatic API reference
|
|
383
|
+
- **[v2.1 Architecture Plan](docs/v2.1-architecture-plan.md)**: Embeddable relay engine design
|
|
384
|
+
- **[v2.0 Architecture Plan](docs/v2-architecture-plan.md)**: Multi-destination design with 7 DRs
|
|
385
|
+
- **[Configuration Reference](configuration-reference.md)**: Complete config guide (YAML + programmatic)
|
|
386
|
+
- **[Deployment Guide](docs/deployment-guide.md)**: Installation and systemd setup
|
|
387
|
+
- **[Metrics Guide](docs/metrics-guide.md)**: Prometheus metrics reference
|
|
388
|
+
- **[Bluetooth Recovery](docs/bluetooth-recovery.md)**: Self-healing Bluetooth GPS
|
|
389
|
+
|
|
390
|
+
## License
|
|
391
|
+
|
|
392
|
+
MIT License โ see [LICENSE](LICENSE).
|
|
393
|
+
|
|
394
|
+
## Project Status
|
|
395
|
+
|
|
396
|
+
**Current Version**: 2.1.0
|
|
397
|
+
- โ
Multi-destination broadcast (Sure-Path, NTRIP v1.0/v2.0, TCP server)
|
|
398
|
+
- โ
Per-destination message filtering and Prometheus metrics
|
|
399
|
+
- โ
BroadcastHub fan-out architecture with independent fault isolation
|
|
400
|
+
- โ
Embeddable RelayEngine API with EventBus and typed status (v2.1)
|
|
401
|
+
- โ
1,106 tests, 88% coverage, production-stable
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
**Made with โค๏ธ for the RTK GPS community**
|