chore(adr-125 iter 1): fix C6 COM port + ship HAP-python reference impl
Two changes from the ADR-125 e2e bootstrap session: 1. CLAUDE.md hardware table: COM4 -> COM12 for ESP32-C6 (the C6 + Seeed MR60BHA2 dev kit now enumerates on COM12 on ruvzen, not COM4 as previously documented). Same fix applied to the ESP32-S3 row (COM7 -> COM9) which CLAUDE.local.md already covered but the top-level table had not been updated. 2. scripts/hap-test-sensor.py — the ~80 LOC HAP-python sidecar that ADR-125 §2.1.a names as the reference implementation. Already running on ruv-mac-mini, already paired with operator's iPhone (paired_clients: 1), already round-trips a MotionDetected characteristic from a touch-file toggle through the HomePod (as Home Hub) to the Home app. Substrate validated for iter 2+: - C6 provisioned on ruv.net (IP 192.168.1.179, ch 5, RSSI -38) - UDP frames: 44 packets in 8s @ mac-mini:5005 (~5.5 pps) - HAP bridge paired and live Refs ADR-125, #794. Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
parent
82fecbb5ad
commit
19b445f9bb
|
|
@ -73,9 +73,9 @@ All 5 ruvector crates integrated in workspace:
|
|||
|
||||
| Device | Port | Chip | Role | Cost |
|
||||
|--------|------|------|------|------|
|
||||
| ESP32-S3 (8MB flash) | COM7 | Xtensa dual-core | WiFi CSI sensing node | ~$9 |
|
||||
| ESP32-S3 (8MB flash) | COM9 (ruvzen, was COM7) | Xtensa dual-core | WiFi CSI sensing node | ~$9 |
|
||||
| ESP32-S3 SuperMini (4MB) | — | Xtensa dual-core | WiFi CSI (compact) | ~$6 |
|
||||
| ESP32-C6 + Seeed MR60BHA2 | COM4 | RISC-V + 60 GHz FMCW | mmWave HR/BR/presence | ~$15 |
|
||||
| ESP32-C6 + Seeed MR60BHA2 | COM12 (ruvzen, was COM4) | RISC-V + 60 GHz FMCW | mmWave HR/BR/presence + WiFi CSI | ~$15 |
|
||||
| HLK-LD2410 | — | 24 GHz FMCW | Presence + distance | ~$3 |
|
||||
|
||||
**Not supported:** ESP32 (original), ESP32-C3 — single-core, can't run CSI DSP pipeline.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
hap-test-sensor.py — ADR-125 §2.1.a smoke test.
|
||||
|
||||
Stands up a single HomeKit Accessory Protocol (HAP-1.1) bridge with one
|
||||
child MotionSensor named "RuView Test Motion". Once paired in the Apple
|
||||
Home app, the HomePod (acting as Home Hub) sees state changes when
|
||||
TOGGLE_FILE (default /tmp/ruview-motion) is touched / removed.
|
||||
|
||||
Usage:
|
||||
python3 hap-test-sensor.py
|
||||
|
||||
Pair from iPhone: Home app -> Add Accessory -> More Options -> "RuView Test Bridge".
|
||||
The setup code is printed on stdout AND written to ~/.ruview-hap/setup-code.txt.
|
||||
|
||||
Trigger motion: touch /tmp/ruview-motion
|
||||
Clear motion: rm /tmp/ruview-motion
|
||||
|
||||
State persists across restarts in ~/.ruview-hap/accessory.state.
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import signal
|
||||
|
||||
from pyhap.accessory import Accessory, Bridge
|
||||
from pyhap.accessory_driver import AccessoryDriver
|
||||
from pyhap.const import CATEGORY_SENSOR, CATEGORY_BRIDGE
|
||||
|
||||
STATE_DIR = Path(os.path.expanduser("~/.ruview-hap"))
|
||||
STATE_DIR.mkdir(exist_ok=True)
|
||||
STATE_FILE = STATE_DIR / "accessory.state"
|
||||
SETUP_CODE_FILE = STATE_DIR / "setup-code.txt"
|
||||
TOGGLE_FILE = Path(os.environ.get("RUVIEW_MOTION_TOGGLE", "/tmp/ruview-motion"))
|
||||
|
||||
|
||||
class RuViewMotion(Accessory):
|
||||
category = CATEGORY_SENSOR
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
serv = self.add_preload_service("MotionSensor")
|
||||
self.char_motion = serv.configure_char("MotionDetected")
|
||||
self._last = False
|
||||
|
||||
@Accessory.run_at_interval(1.0)
|
||||
def run(self):
|
||||
present = TOGGLE_FILE.exists()
|
||||
if present != self._last:
|
||||
self.char_motion.set_value(present)
|
||||
self._last = present
|
||||
print(
|
||||
f"[hap-test] MotionDetected -> {present} (toggle file: {TOGGLE_FILE})",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
driver = AccessoryDriver(port=51826, persist_file=str(STATE_FILE))
|
||||
|
||||
bridge = Bridge(driver, "RuView Test Bridge")
|
||||
bridge.category = CATEGORY_BRIDGE
|
||||
bridge.add_accessory(RuViewMotion(driver, "RuView Test Motion"))
|
||||
driver.add_accessory(accessory=bridge)
|
||||
|
||||
setup_code = driver.state.pincode.decode() if hasattr(driver.state.pincode, "decode") else driver.state.pincode
|
||||
SETUP_CODE_FILE.write_text(str(setup_code) + "\n")
|
||||
print(f"[hap-test] HAP bridge advertising as 'RuView Test Bridge'")
|
||||
print(f"[hap-test] iPhone pair flow: Home app -> Add Accessory -> More Options")
|
||||
print(f"[hap-test] Setup code (also in {SETUP_CODE_FILE}): {setup_code}")
|
||||
print(f"[hap-test] Motion toggle file: {TOGGLE_FILE}")
|
||||
print(f"[hap-test] State persists in: {STATE_FILE}")
|
||||
|
||||
signal.signal(signal.SIGTERM, lambda *_: driver.stop())
|
||||
driver.start()
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Loading…
Reference in New Issue