From 200f2e17519d469d2530328d8ef5d4d4d50d72a1 Mon Sep 17 00:00:00 2001 From: Eli Yip Date: Wed, 4 Jun 2025 09:51:00 +0800 Subject: [PATCH] feat: implement legacy status api --- api/legacy/handlers.go | 32 +++++------------ communication/communicator.go | 67 +++++++++++++++++------------------ device/device.go | 1 + device/models/l10.go | 4 +++ 4 files changed, 47 insertions(+), 57 deletions(-) diff --git a/api/legacy/handlers.go b/api/legacy/handlers.go index 77556f7..07ce395 100644 --- a/api/legacy/handlers.go +++ b/api/legacy/handlers.go @@ -508,6 +508,13 @@ func (s *LegacyServer) handleStatus(c *gin.Context) { // 检查 CAN 服务状态 - 通过尝试获取设备状态来判断 canStatus := make(map[string]bool) + for ifName, handConfig := range allHandConfigs { + handConfigsData[ifName] = map[string]any{ + "handType": handConfig.HandType, + "handId": handConfig.HandId, + } + } + for _, ifName := range config.Config.AvailableInterfaces { // 获取对应的设备 dev, err := s.mapper.GetDeviceForInterface(ifName) @@ -525,32 +532,11 @@ func (s *LegacyServer) handleStatus(c *gin.Context) { animationStatus[ifName] = animEngine.IsRunning() // 获取设备状态来判断 CAN 服务状态 - status, err := dev.GetStatus() + rawCanStatus, err := dev.GetCanStatus() if err != nil { canStatus[ifName] = false } else { - canStatus[ifName] = status.IsConnected && status.IsActive - } - - // 获取手型配置 - if handConfig, exists := allHandConfigs[ifName]; exists { - handConfigsData[ifName] = map[string]any{ - "handType": handConfig.HandType, - "handId": handConfig.HandId, - } - } else { - // 从设备获取当前手型 - handType := dev.GetHandType() - handTypeStr := "right" - handId := uint32(define.HAND_TYPE_RIGHT) - if handType == define.HAND_TYPE_LEFT { - handTypeStr = "left" - handId = uint32(define.HAND_TYPE_LEFT) - } - handConfigsData[ifName] = map[string]any{ - "handType": handTypeStr, - "handId": handId, - } + canStatus[ifName] = rawCanStatus[ifName] } } diff --git a/communication/communicator.go b/communication/communicator.go index 978840d..4b19639 100644 --- a/communication/communicator.go +++ b/communication/communicator.go @@ -5,6 +5,8 @@ import ( "context" "encoding/json" "fmt" + "hands/config" + "hands/define" "io" "net/http" "time" @@ -23,9 +25,6 @@ type Communicator interface { // SendMessage 将 RawMessage 通过 HTTP POST 请求发送到 can-bridge 服务 SendMessage(ctx context.Context, msg RawMessage) error - // GetInterfaceStatus 获取指定 CAN 接口的状态 - GetInterfaceStatus(ifName string) (isActive bool, err error) - // GetAllInterfaceStatuses 获取所有已知 CAN 接口的状态 GetAllInterfaceStatuses() (statuses map[string]bool, err error) @@ -45,9 +44,7 @@ type CanBridgeClient struct { func NewCanBridgeClient(serviceURL string) Communicator { return &CanBridgeClient{ serviceURL: serviceURL, - client: &http.Client{ - Timeout: 5 * time.Second, - }, + client: &http.Client{Timeout: 5 * time.Second}, } } @@ -60,7 +57,7 @@ func (c *CanBridgeClient) SendMessage(ctx context.Context, msg RawMessage) error url := fmt.Sprintf("%s/api/can", c.serviceURL) // 创建带有 context 的请求 - req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(jsonData)) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewBuffer(jsonData)) if err != nil { return fmt.Errorf("创建 HTTP 请求失败:%w", err) } @@ -80,47 +77,49 @@ func (c *CanBridgeClient) SendMessage(ctx context.Context, msg RawMessage) error return nil } -func (c *CanBridgeClient) GetInterfaceStatus(ifName string) (bool, error) { - url := fmt.Sprintf("%s/api/status/%s", c.serviceURL, ifName) - resp, err := c.client.Get(url) - if err != nil { - return false, fmt.Errorf("获取接口状态失败:%w", err) - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return false, fmt.Errorf("can-bridge 服务返回错误:%d", resp.StatusCode) - } - - var status struct { - Active bool `json:"active"` - } - - if err := json.NewDecoder(resp.Body).Decode(&status); err != nil { - return false, fmt.Errorf("解析状态响应失败:%w", err) - } - - return status.Active, nil -} - func (c *CanBridgeClient) GetAllInterfaceStatuses() (map[string]bool, error) { + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + url := fmt.Sprintf("%s/api/status", c.serviceURL) - resp, err := c.client.Get(url) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { return nil, fmt.Errorf("获取所有接口状态失败:%w", err) } + + resp, err := c.client.Do(req) + if err != nil { + return nil, fmt.Errorf("发送 HTTP 请求失败:%w", err) + } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("can-bridge 服务返回错误:%d", resp.StatusCode) } - var statuses map[string]bool - if err := json.NewDecoder(resp.Body).Decode(&statuses); err != nil { + var statusResp define.ApiResponse + if err := json.NewDecoder(resp.Body).Decode(&statusResp); err != nil { return nil, fmt.Errorf("解析状态响应失败:%w", err) } - return statuses, nil + result := make(map[string]bool) + for _, ifName := range config.Config.AvailableInterfaces { + result[ifName] = false + } + + if statusData, ok := statusResp.Data.(map[string]interface{}); ok { + if interfaces, ok := statusData["interfaces"].(map[string]interface{}); ok { + for ifName, ifStatus := range interfaces { + if status, ok := ifStatus.(map[string]interface{}); ok { + if active, ok := status["active"].(bool); ok { + result[ifName] = active + } + } + } + } + } + + return result, nil } func (c *CanBridgeClient) SetServiceURL(url string) { c.serviceURL = url } diff --git a/device/device.go b/device/device.go index 6b69425..ebc7df6 100644 --- a/device/device.go +++ b/device/device.go @@ -14,6 +14,7 @@ type Device interface { ExecuteCommand(cmd Command) error // 执行一个通用指令 ReadSensorData() (SensorData, error) // 读取特定传感器数据 GetComponents(componentType ComponentType) []Component // 获取指定类型的组件 + GetCanStatus() (map[string]bool, error) GetStatus() (DeviceStatus, error) // 获取设备状态 Connect() error // 连接设备 Disconnect() error // 断开设备连接 diff --git a/device/models/l10.go b/device/models/l10.go index 280816d..de953db 100644 --- a/device/models/l10.go +++ b/device/models/l10.go @@ -372,3 +372,7 @@ func (h *L10Hand) GetPresetDescription(presetName string) string { func (h *L10Hand) GetPresetDetails(presetName string) (device.PresetPose, bool) { return h.presetManager.GetPreset(presetName) } + +func (h *L10Hand) GetCanStatus() (map[string]bool, error) { + return h.communicator.GetAllInterfaceStatuses() +}