Download protocol_stack/tools/live_ble_telemetry_ingest.py from DeepSeekOracle/LYGO-Resonance-Engine: direct link, hf CLI and curl.
- Browser
- Download file 7.73 kB
-
https://huggingface.co/spaces/DeepSeekOracle/LYGO-Resonance-Engine/resolve/main/protocol_stack/tools/live_ble_telemetry_ingest.py
- Command line
-
hf download hf://spaces/DeepSeekOracle/LYGO-Resonance-Engine/protocol_stack/tools/live_ble_telemetry_ingest.py
-
curl -L -o live_ble_telemetry_ingest.py https://huggingface.co/spaces/DeepSeekOracle/LYGO-Resonance-Engine/resolve/main/protocol_stack/tools/live_ble_telemetry_ingest.py
7.73 kB
| #!/usr/bin/env python3 | |
| """ | |
| LYGO Phase 7 — Live BLE telemetry ingest (GATT 0x180D) + optional WebSocket broadcast. | |
| Biophase7 Objective: ws://0.0.0.0:8788 for tunnel → HF Space (LYGO_BLE_WS_URL). | |
| Signature: Δ9Φ963-PHASE7-BLE-LIVE-HARNESS | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import asyncio | |
| import json | |
| import sys | |
| import time | |
| from pathlib import Path | |
| ROOT = Path(__file__).resolve().parents[1] | |
| WORKSPACE = ROOT / "tools" / "lygo_control_center" / "workspace" | |
| WORKSPACE.mkdir(parents=True, exist_ok=True) | |
| SEED_JSON = WORKSPACE / "latest_seed.json" | |
| BUFFER_THRESHOLD = 64 | |
| sys.path.insert(0, str(ROOT)) | |
| from protocol7_human_ai_interface.ble_gatt import ( # noqa: E402 | |
| HR_MEASUREMENT_CHAR_UUID, | |
| HR_SERVICE_UUID, | |
| bleak_available, | |
| parse_heart_rate_measurement, | |
| ) | |
| from protocol7_human_ai_interface.entropy_extraction import extract_p0_seed_from_ibi # noqa: E402 | |
| from protocol7_human_ai_interface import live_stream_hub as hub # noqa: E402 | |
| ENTROPY_BUFFER: list[int] = [] | |
| def _preview_h_min(ibi: list[int]) -> float | None: | |
| if len(ibi) < 4: | |
| return None | |
| pack = extract_p0_seed_from_ibi([float(x) for x in ibi[-min(32, len(ibi)) :]]) | |
| return pack.get("h_min") | |
| def _flush_seed(ibi: list[int], *, source: str = "ble") -> dict: | |
| pack = extract_p0_seed_from_ibi([float(x) for x in ibi]) | |
| seed = str(pack.get("seed_256", "")) | |
| h_min = pack.get("h_min") | |
| payload = { | |
| "timestamp": time.time(), | |
| "signature": "Δ9Φ963-PHASE7-BLE-LIVE-HARNESS", | |
| "ibi_count": len(ibi), | |
| "h_min": h_min, | |
| "seed_256": seed, | |
| "seed_preview": seed[:16], | |
| } | |
| SEED_JSON.write_text(json.dumps(payload, indent=2), encoding="utf-8") | |
| hub.record_seed(seed, h_min=h_min, ibi_count=len(ibi), source=source) | |
| try: | |
| from tools.ble_ws_broadcast_server import schedule_broadcast | |
| schedule_broadcast(hub.ws_message_seed(seed, h_min=h_min, ibi_count=len(ibi))) | |
| except Exception: | |
| pass | |
| return payload | |
| def handle_notification(data: bytes, *, source: str = "ble") -> None: | |
| global ENTROPY_BUFFER | |
| parsed = parse_heart_rate_measurement(data) | |
| for ibi in parsed.get("ibi_ms") or []: | |
| ENTROPY_BUFFER.append(int(ibi)) | |
| h_est = _preview_h_min(ENTROPY_BUFFER) | |
| hub.record_ibi(int(ibi), len(ENTROPY_BUFFER), h_min=h_est, source=source) | |
| try: | |
| from tools.ble_ws_broadcast_server import schedule_broadcast | |
| schedule_broadcast(hub.ws_message_ibi(int(ibi), len(ENTROPY_BUFFER), h_min=h_est)) | |
| except Exception: | |
| pass | |
| print(f"[+] IBI: {ibi}ms | buffer {len(ENTROPY_BUFFER)}/{BUFFER_THRESHOLD}") | |
| if len(ENTROPY_BUFFER) >= BUFFER_THRESHOLD: | |
| print("[!] Threshold reached — extracting P0 seed...") | |
| out = _flush_seed(ENTROPY_BUFFER.copy(), source=source) | |
| print(f"[>] H_min={out['h_min']} seed={out['seed_preview']}…") | |
| ENTROPY_BUFFER.clear() | |
| async def _live_loop(scan_timeout: float = 8.0) -> int: | |
| from bleak import BleakClient, BleakScanner | |
| print("=" * 70) | |
| print("LYGO PHASE 7 — LIVE BLE TELEMETRY INGEST") | |
| print("Δ9Φ963-PHASE7-BLE-LIVE-HARNESS") | |
| print("=" * 70) | |
| hub.reset("ble") | |
| devices = await BleakScanner.discover(timeout=scan_timeout) | |
| target = None | |
| for d in devices: | |
| uuids = (d.metadata or {}).get("uuids") or [] | |
| if HR_SERVICE_UUID in uuids or (d.name and "heart" in d.name.lower()): | |
| target = d | |
| print(f"[+] Candidate: {d.name} [{d.address}]") | |
| break | |
| if target is None and devices: | |
| target = devices[0] | |
| print(f"[*] No HR service UUID — trying first device: {target.name} [{target.address}]") | |
| if target is None: | |
| print("[-] No BLE devices found.") | |
| return 1 | |
| def _cb(_sender, data: bytearray) -> None: | |
| handle_notification(bytes(data)) | |
| async with BleakClient(target.address) as client: | |
| await client.start_notify(HR_MEASUREMENT_CHAR_UUID, _cb) | |
| print(f"[+] Subscribed to {HR_MEASUREMENT_CHAR_UUID} — Ctrl+C to stop") | |
| while True: | |
| await asyncio.sleep(1) | |
| async def _simulate_stream(interval: float = 0.35, count: int = 80) -> None: | |
| """Emit synthetic IBI over WebSocket for HF/tunnel verification without hardware.""" | |
| import random | |
| hub.reset("simulate") | |
| rng = random.Random(528963) | |
| for _ in range(count): | |
| ibi = int(60000 / 75 + rng.uniform(-40, 40)) | |
| handle_notification(_fake_hr_pdu(ibi), source="simulate") | |
| await asyncio.sleep(interval) | |
| def _fake_hr_pdu(ibi_ms: int) -> bytes: | |
| """Minimal GATT 0x2A37 PDU with one RR interval.""" | |
| rr = int((ibi_ms / 1000.0) * 1024) | |
| hr = max(40, min(180, int(60000 / max(ibi_ms, 300)))) | |
| return bytes([0x10, hr, rr & 0xFF, (rr >> 8) & 0xFF]) | |
| def run_simulated_flush(n: int = 64) -> dict: | |
| import random | |
| rng = random.Random(528963) | |
| ibi = [int(60000 / 75 + rng.uniform(-40, 40)) for _ in range(n)] | |
| hub.reset("simulate") | |
| return _flush_seed(ibi, source="simulate") | |
| async def _run_with_ws( | |
| *, | |
| host: str, | |
| port: int, | |
| simulate_stream: bool, | |
| scan_timeout: float, | |
| ) -> int: | |
| from tools.ble_ws_broadcast_server import run_server | |
| server_task = asyncio.create_task(run_server(host, port)) | |
| await asyncio.sleep(0.3) | |
| if simulate_stream: | |
| await _simulate_stream() | |
| print("[*] Synthetic stream complete — WebSocket still listening (Ctrl+C to exit)") | |
| try: | |
| await server_task | |
| except asyncio.CancelledError: | |
| pass | |
| return 0 | |
| code = await _live_loop(scan_timeout) | |
| server_task.cancel() | |
| return code | |
| def main() -> int: | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--simulate", action="store_true", help="Write seed from synthetic IBI (no BLE)") | |
| ap.add_argument("--with-ws", action="store_true", help="Run WebSocket broadcast alongside ingest") | |
| ap.add_argument("--ws-host", default="0.0.0.0") | |
| ap.add_argument("--ws-port", type=int, default=8788) | |
| ap.add_argument("--simulate-stream", action="store_true", help="With --with-ws: stream synthetic IBI over WS") | |
| ap.add_argument("--scan-timeout", type=float, default=8.0) | |
| args = ap.parse_args() | |
| if args.simulate: | |
| out = run_simulated_flush() | |
| print(json.dumps(out, indent=2)) | |
| return 0 | |
| if args.with_ws: | |
| if args.simulate_stream: | |
| try: | |
| return asyncio.run( | |
| _run_with_ws( | |
| host=args.ws_host, port=args.ws_port, simulate_stream=True, scan_timeout=args.scan_timeout | |
| ) | |
| ) | |
| except KeyboardInterrupt: | |
| return 0 | |
| if not bleak_available() and not args.simulate_stream: | |
| print("bleak not installed — pip install bleak OR --simulate-stream", file=sys.stderr) | |
| return 1 | |
| try: | |
| return asyncio.run( | |
| _run_with_ws(host=args.ws_host, port=args.ws_port, simulate_stream=False, scan_timeout=args.scan_timeout) | |
| ) | |
| except KeyboardInterrupt: | |
| print("\n[!] Ingestion stopped.") | |
| if ENTROPY_BUFFER: | |
| _flush_seed(ENTROPY_BUFFER) | |
| return 0 | |
| if not bleak_available(): | |
| print("bleak not installed — pip install bleak OR use --simulate", file=sys.stderr) | |
| return 1 | |
| try: | |
| return asyncio.run(_live_loop(args.scan_timeout)) | |
| except KeyboardInterrupt: | |
| print("\n[!] Ingestion stopped.") | |
| if ENTROPY_BUFFER: | |
| _flush_seed(ENTROPY_BUFFER) | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) |