Add LED ring control per client and broadcast over REST and WebSocket.
Solid color mode fills all ring LEDs; master routes UART commands to slaves via ESPNOW_LED_RING. goTool exposes POST /api/led-ring, WebSocket set_led_ring, and a dashboard LED panel with master/slave/all targets. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+28
-4
@@ -132,7 +132,9 @@ func (h *accelStreamHub) register(conn *websocket.Conn, portName string) *wsSubs
|
||||
Type: "hello",
|
||||
Serial: portName,
|
||||
IntervalMs: int(h.defaultInterval / time.Millisecond),
|
||||
Commands: []string{"set_stream", "get_stream", "set_accel_stream", "get_accel_stream"},
|
||||
Commands: []string{
|
||||
"set_stream", "get_stream", "set_accel_stream", "get_accel_stream", "set_led_ring",
|
||||
},
|
||||
}
|
||||
if data, err := json.Marshal(hello); err == nil {
|
||||
_ = conn.WriteMessage(websocket.TextMessage, data)
|
||||
@@ -317,6 +319,15 @@ func writeStreamStatus(conn *websocket.Conn, msg StreamStatusMessage) {
|
||||
_ = conn.WriteMessage(websocket.TextMessage, data)
|
||||
}
|
||||
|
||||
func writeLedRingStatus(conn *websocket.Conn, out ledRingAPIResponse) {
|
||||
out.Type = "led_ring_status"
|
||||
data, err := json.Marshal(out)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_ = conn.WriteMessage(websocket.TextMessage, data)
|
||||
}
|
||||
|
||||
func writeAccelStreamStatus(conn *websocket.Conn, out accelStreamAPIResponse) {
|
||||
msg := AccelStreamStatusMessage{
|
||||
Type: "accel_stream_status",
|
||||
@@ -393,10 +404,22 @@ func handleAccelWSCommand(conn *websocket.Conn, sub *wsSubscriber, data []byte,
|
||||
Success: resp.GetSuccess(),
|
||||
})
|
||||
|
||||
case "set_led_ring":
|
||||
var body ledRingAPIRequest
|
||||
if err := json.Unmarshal(data, &body); err != nil {
|
||||
writeLedRingStatus(conn, ledRingAPIResponse{Error: "invalid JSON"})
|
||||
return
|
||||
}
|
||||
if body.Mode == "" {
|
||||
writeLedRingStatus(conn, ledRingAPIResponse{Error: "mode required"})
|
||||
return
|
||||
}
|
||||
writeLedRingStatus(conn, applyLedRing(link, body))
|
||||
|
||||
default:
|
||||
writeStreamStatus(conn, StreamStatusMessage{
|
||||
Type: "stream_status",
|
||||
Error: "unknown type (set_stream, get_stream, set_accel_stream, get_accel_stream)",
|
||||
Type: "stream_status",
|
||||
Error: "unknown type (set_stream, get_stream, set_accel_stream, get_accel_stream, set_led_ring)",
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -434,7 +457,7 @@ func mountExternalAPI(mux *http.ServeMux, portName string, defaultInterval time.
|
||||
DefaultIntervalMs: defMs,
|
||||
MinIntervalMs: int(minAPIStreamInterval / time.Millisecond),
|
||||
MaxIntervalMs: int(maxAPIStreamInterval / time.Millisecond),
|
||||
Description: "WebSocket: per-connection accel receive + interval; slave stream via set_accel_stream",
|
||||
Description: "WebSocket: accel stream + set_led_ring (modes: clear, color, progress, digit, blink, find-me)",
|
||||
})
|
||||
})
|
||||
|
||||
@@ -454,6 +477,7 @@ func runAPIServer(portName string, link *managedSerial, addr string, defaultInte
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mountExternalAPI(mux, portName, defaultInterval, hub, link, dash, ctl)
|
||||
mountLedRingAPI(mux, link)
|
||||
|
||||
srv := &http.Server{Addr: addr, Handler: mux}
|
||||
go func() {
|
||||
|
||||
Reference in New Issue
Block a user