Add goTool web dashboard with UART auto-reconnect.
Serve polls the master over UART and pushes live state via WebSocket; reopens the serial port when the device is unplugged and comes back. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
//go:embed webui/*
|
||||
var webUI embed.FS
|
||||
|
||||
var wsUpgrader = websocket.Upgrader{
|
||||
CheckOrigin: func(r *http.Request) bool { return true },
|
||||
}
|
||||
|
||||
func runServe(portName string, baud int, args []string) error {
|
||||
serveFlags := flag.NewFlagSet("serve", flag.ExitOnError)
|
||||
addr := serveFlags.String("addr", ":8080", "HTTP listen address")
|
||||
interval := serveFlags.Duration("interval", 2*time.Second, "UART poll interval")
|
||||
if err := serveFlags.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
if portName == "" {
|
||||
return fmt.Errorf("serve requires -port (master UART)")
|
||||
}
|
||||
|
||||
link := newManagedSerial(portName, baud)
|
||||
link.quiet = true
|
||||
defer link.Close()
|
||||
|
||||
hub := newWSHub()
|
||||
stop := make(chan struct{})
|
||||
defer close(stop)
|
||||
go runPoller(link, portName, hub, *interval, stop)
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
|
||||
conn, err := wsUpgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
log.Printf("websocket upgrade: %v", err)
|
||||
return
|
||||
}
|
||||
hub.register(conn)
|
||||
defer hub.unregister(conn)
|
||||
defer conn.Close()
|
||||
|
||||
for {
|
||||
if _, _, err := conn.ReadMessage(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
ui, err := fs.Sub(webUI, "webui")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mux.Handle("/", http.FileServer(http.FS(ui)))
|
||||
|
||||
log.Printf("dashboard http://localhost%s (UART %s @ %d baud, poll %s, auto-reconnect)",
|
||||
*addr, portName, baud, interval.String())
|
||||
return http.ListenAndServe(*addr, mux)
|
||||
}
|
||||
Reference in New Issue
Block a user