Add dynamic UART/BLE host connect for serve, dashboard, and WS.
Serve starts without a required port; REST/WS/UI can scan and switch transports, with BLE live ticks and UART-only OTA. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+40
-10
@@ -20,21 +20,48 @@ var wsUpgrader = websocket.Upgrader{
|
||||
CheckOrigin: func(r *http.Request) bool { return true },
|
||||
}
|
||||
|
||||
func runServe(portName string, baud int, args []string) error {
|
||||
type serveOpts struct {
|
||||
portName string
|
||||
baud int
|
||||
useBLE bool
|
||||
bleName string
|
||||
settle time.Duration
|
||||
}
|
||||
|
||||
func runServe(opts serveOpts, args []string) error {
|
||||
serveFlags := flag.NewFlagSet("serve", flag.ExitOnError)
|
||||
addr := serveFlags.String("addr", ":8080", "dashboard HTTP listen address")
|
||||
apiAddr := serveFlags.String("api-addr", ":8081", "external API HTTP listen address (empty to disable)")
|
||||
accelInterval := serveFlags.Duration("accel-interval", defaultAccelStreamInterval, "accel WebSocket sample period on API server")
|
||||
interval := serveFlags.Duration("interval", 2*time.Second, "UART poll interval")
|
||||
interval := serveFlags.Duration("interval", 2*time.Second, "host poll interval")
|
||||
if err := serveFlags.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
if portName == "" {
|
||||
return fmt.Errorf("serve requires -port (master UART)")
|
||||
if opts.useBLE && opts.portName != "" {
|
||||
return fmt.Errorf("use either -port or -ble, not both")
|
||||
}
|
||||
|
||||
link := newManagedSerial(portName, baud)
|
||||
link := newManagedHost(opts.baud)
|
||||
link.quiet = true
|
||||
link.settle = opts.settle
|
||||
if opts.settle <= 0 {
|
||||
link.settle = time.Second
|
||||
}
|
||||
|
||||
switch {
|
||||
case opts.portName != "":
|
||||
if err := link.ConnectUART(opts.portName, opts.baud); err != nil {
|
||||
log.Printf("initial UART connect failed (UI can retry): %v", err)
|
||||
}
|
||||
case opts.useBLE:
|
||||
name := opts.bleName
|
||||
if name == "" {
|
||||
name = bleDefaultName
|
||||
}
|
||||
if err := link.ConnectBLE("", name); err != nil {
|
||||
log.Printf("initial BLE connect failed (UI can scan/retry): %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
hub := newWSHub()
|
||||
streamCtl := newAccelStreamCtl()
|
||||
@@ -48,16 +75,17 @@ func runServe(portName string, baud int, args []string) error {
|
||||
shutdownHTTPServer(dashSrv)
|
||||
shutdownAPIServer(apiSrv)
|
||||
if err := link.Close(); err != nil {
|
||||
log.Printf("UART close: %v", err)
|
||||
log.Printf("host close: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
go runPoller(link, portName, hub, streamCtl, tapCtl, *interval, stop)
|
||||
go runPoller(link, link.Endpoint(), hub, streamCtl, tapCtl, *interval, stop)
|
||||
go runBatteryPoller(link, hub, 5*time.Second, stop)
|
||||
go runCacheStatusDashboardPoller(link, hub, *accelInterval, stop)
|
||||
go runBLEStreamDashboardPoller(link, hub, streamCtl, stop)
|
||||
|
||||
if *apiAddr != "" {
|
||||
apiSrv = runAPIServer(portName, link, *apiAddr, *accelInterval, hub, streamCtl, tapCtl, stop)
|
||||
apiSrv = runAPIServer(link.Endpoint(), link, *apiAddr, *accelInterval, hub, streamCtl, tapCtl, stop)
|
||||
}
|
||||
|
||||
mux := http.NewServeMux()
|
||||
@@ -85,10 +113,12 @@ func runServe(portName string, baud int, args []string) error {
|
||||
}
|
||||
mux.Handle("/", http.FileServer(http.FS(ui)))
|
||||
|
||||
log.Printf("dashboard http://localhost%s (UART %s @ %d baud, poll %s, live-stream %s, auto-reconnect)",
|
||||
*addr, portName, baud, interval.String(), accelInterval.String())
|
||||
log.Printf("dashboard http://localhost%s (transport=%s endpoint=%q poll %s, live-stream %s)",
|
||||
*addr, link.Transport(), link.Endpoint(), interval.String(), accelInterval.String())
|
||||
if *apiAddr == "" {
|
||||
log.Printf("external API disabled (-api-addr \"\")")
|
||||
} else {
|
||||
log.Printf("external API http://localhost%s ws://localhost%s/ws", *apiAddr, *apiAddr)
|
||||
}
|
||||
|
||||
dashSrv = &http.Server{Addr: *addr, Handler: mux}
|
||||
|
||||
Reference in New Issue
Block a user