feat: implement legacy status api

This commit is contained in:
Eli Yip 2025-06-04 09:51:00 +08:00
parent f8aa2138ab
commit 200f2e1751
No known key found for this signature in database
GPG Key ID: C98B69D4CF7D7EC5
4 changed files with 47 additions and 57 deletions

View File

@ -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]
}
}

View File

@ -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 }

View File

@ -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 // 断开设备连接

View File

@ -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()
}