Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,18 @@ Python SDK for building Hubble Network BLE gateways. Import `hubble_gateway` in

gateway-api sends a `config` object (or `null`) in the registration, heartbeat
and token-refresh responses. `GatewayAuth` stores it as `server_config`.
`GatewaySender` reads it on every use, and `Scanner(auth=...)` reads it before
each scan cycle, so each new response takes effect without a restart.
`GatewaySender` reads it on every use, so each new response takes effect
without a restart.

| Key | Range | Overrides |
| --- | --- | --- |
| `uploadIntervalMs` | 60,000 – 3,600,000 | `upload_interval_s` |
| `uploadBatchSize` | 1 – 500 | `batch_size` |
| `dedupWindowMs` | 5,000 – 3,600,000 | `dedup_window_s` |
| `scanServiceUuids` | list, max 16 | `Scanner` `service_uuids` |

- Each response replaces the stored config. It does not merge into it.
- `config: null` clears it, and the local values apply again.
- Out-of-range values are clamped. Values of the wrong type are ignored.
- `scanServiceUuids` replaces the scan list. Only 16-bit services are valid:
the short form (`FCA6`) or its Bluetooth Base form
(`0000FCA6-0000-1000-8000-00805F9B34FB`). Custom 128-bit UUIDs are dropped,
because gateway-api keys packets on 16-bit service IDs. The SDK also drops
duplicates, keeps `FCA6` first, and keeps at most 16.
Server default: `["FCA6", "FEED"]`.
- Uploaded packets carry the 16-bit form (`FCA6`) as `serviceUuid`.
- Other keys (`activeUploadIntervalMs`, `activeDedupWindowMs`,
`uploadOnCellular`) are ignored: this SDK has no motion state or cellular gating.
Expand Down
7 changes: 3 additions & 4 deletions src/hubble_gateway/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
# Server config keys this SDK applies, with the inclusive range gateway-api
# allows for them. gateway-api may also send activeUploadIntervalMs,
# activeDedupWindowMs and uploadOnCellular; Python has no motion state or
# cellular gating, so those are dropped. scanServiceUuids is handled apart
# because it is a list.
# cellular gating, so those are dropped.
SERVER_CONFIG_RANGES: dict[str, tuple[int, int]] = {
"uploadIntervalMs": (60_000, 3_600_000),
"uploadBatchSize": (1, 500),
Expand All @@ -34,12 +33,12 @@


def _sanitize_scan_service_uuids(value: Any) -> list[str] | None:
"""Normalize a server scan list to uppercase 128-bit UUIDs, FCA6 first.
"""Normalize a UUID list to uppercase 128-bit UUIDs, FCA6 first.

Only 16-bit services are valid (short form or written out on the Bluetooth
Base UUID), because gateway-api ingest keys packets on 16-bit service IDs.
Other entries are dropped; FCA6 is always kept, as gateway-api does.
Returns None when the value is not a list, so the local setting applies.
Returns None when the value is not a list.
"""
if not isinstance(value, list):
return None
Expand Down
5 changes: 1 addition & 4 deletions src/hubble_gateway/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@ class Settings(BaseSettings):
# BLE scanning
service_uuids: list[str] = Field(
default=DEFAULT_SERVICE_UUIDS,
description=(
"BLE service UUIDs to scan for. Server scanServiceUuids replaces this "
"list when the Scanner is given auth."
),
description="BLE service UUIDs to scan for",
)
scan_duration_seconds: float = Field(
default=5.0,
Expand Down
4 changes: 0 additions & 4 deletions src/hubble_gateway/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ class Scanner:
Supports scanning for multiple UUIDs simultaneously (e.g. Hubble FCA6
and Tile FEED). Works with both internal BLE adapters and external USB
dongles — pass ``adapter='hci1'`` to select a specific adapter.

Pass ``auth`` to let the server's ``scanServiceUuids`` replace
``service_uuids``. The list is re-read before each scan cycle, so a new
server list applies at the next cycle without a restart.
"""

def __init__(
Expand Down
Loading