4b35736f73
P0 (5): crypto/rand session ID, TTS fallback可达性, goroutine defer recover, adminAuth前缀修正 P1 (5): 普通用户密码验证, context传递, priority clamp, 超时重试, 自主思考速率限制 P2 (4): Briefing AI降级, 前端消息类型渲染, Docker Compose补全, PWA 192图标 P3 (5): goroutine错误处理, .gitignore完善, reminder created_at, voice Dockerfile, Go版本更新
135 lines
3.5 KiB
Go
135 lines
3.5 KiB
Go
package tools
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// IoTQueryTool IoT 设备查询工具
|
|
type IoTQueryTool struct {
|
|
iotClient *IoTClient
|
|
}
|
|
|
|
// NewIoTQueryTool 创建 IoT 查询工具
|
|
func NewIoTQueryTool(iotClient *IoTClient) *IoTQueryTool {
|
|
return &IoTQueryTool{iotClient: iotClient}
|
|
}
|
|
|
|
// Definition 返回工具定义
|
|
func (t *IoTQueryTool) Definition() ToolDefinition {
|
|
return ToolDefinition{
|
|
Name: "iot_query",
|
|
Description: "查询家中智能设备状态。注意:当前设备状态通常已自动注入到系统提示词中,你通常不需要调用此工具即可回答设备状态问题。只有在设备状态信息陈旧或明显不完整时才调用此工具刷新。",
|
|
Parameters: map[string]interface{}{
|
|
"type": "object",
|
|
"properties": map[string]interface{}{
|
|
"device_id": map[string]interface{}{
|
|
"type": "string",
|
|
"description": "要查询的设备ID(可选,不填则返回所有设备)。可选值: light-livingroom, light-bedroom, ac-livingroom, ac-bedroom, curtain-livingroom, sensor-temperature, sensor-humidity, lock-door",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// Execute 执行查询
|
|
func (t *IoTQueryTool) Execute(ctx context.Context, arguments map[string]interface{}) (*ToolResult, error) {
|
|
if t.iotClient == nil {
|
|
return &ToolResult{
|
|
ToolName: "iot_query",
|
|
Success: false,
|
|
Error: "IoT 客户端未初始化",
|
|
}, nil
|
|
}
|
|
|
|
deviceID, _ := arguments["device_id"].(string)
|
|
|
|
if deviceID != "" {
|
|
// 查询单个设备
|
|
device, err := t.iotClient.GetDevice(ctx, deviceID)
|
|
if err != nil {
|
|
return &ToolResult{
|
|
ToolName: "iot_query",
|
|
Success: false,
|
|
Error: err.Error(),
|
|
}, nil
|
|
}
|
|
return &ToolResult{
|
|
ToolName: "iot_query",
|
|
Success: true,
|
|
Data: formatSingleDevice(device),
|
|
}, nil
|
|
}
|
|
|
|
// 查询所有设备
|
|
devices, err := t.iotClient.GetAllDevices(ctx)
|
|
if err != nil {
|
|
return &ToolResult{
|
|
ToolName: "iot_query",
|
|
Success: false,
|
|
Error: err.Error(),
|
|
}, nil
|
|
}
|
|
|
|
var result strings.Builder
|
|
result.WriteString(fmt.Sprintf("当前共有 %d 台智能设备:\n\n", len(devices)))
|
|
for _, d := range devices {
|
|
result.WriteString(formatDeviceLine(d) + "\n")
|
|
}
|
|
return &ToolResult{
|
|
ToolName: "iot_query",
|
|
Success: true,
|
|
Data: result.String(),
|
|
}, nil
|
|
}
|
|
|
|
func formatSingleDevice(d *IoTDevice) string {
|
|
return fmt.Sprintf("设备: %s (%s)\n状态: %s", d.Name, d.Type, formatDeviceLine(*d))
|
|
}
|
|
|
|
func formatDeviceLine(d IoTDevice) string {
|
|
switch d.Type {
|
|
case "light":
|
|
if d.Status == "on" {
|
|
return fmt.Sprintf("💡 %s: 开启 (亮度%d%%, %s)", d.Name, d.Brightness, d.Color)
|
|
}
|
|
return fmt.Sprintf("💡 %s: 关闭", d.Name)
|
|
case "ac":
|
|
if d.Status == "on" {
|
|
mode := d.Mode
|
|
switch mode {
|
|
case "cool":
|
|
mode = "制冷"
|
|
case "heat":
|
|
mode = "制热"
|
|
case "auto":
|
|
mode = "自动"
|
|
}
|
|
return fmt.Sprintf("❄️ %s: 运行中 (%s %.0f°C)", d.Name, mode, d.Temperature)
|
|
}
|
|
return fmt.Sprintf("❄️ %s: 关闭", d.Name)
|
|
case "curtain":
|
|
if d.Status == "open" {
|
|
return fmt.Sprintf("🪟 %s: 已打开", d.Name)
|
|
}
|
|
return fmt.Sprintf("🪟 %s: 已关闭", d.Name)
|
|
case "sensor":
|
|
unit := d.Unit
|
|
if unit == "celsius" {
|
|
unit = "°C"
|
|
} else if unit == "percent" {
|
|
unit = "%"
|
|
}
|
|
return fmt.Sprintf("🌡️ %s: %.1f%s", d.Name, d.Value, unit)
|
|
case "lock":
|
|
status := "已锁定"
|
|
if d.Status == "unlocked" {
|
|
status = "已解锁"
|
|
}
|
|
return fmt.Sprintf("🔒 %s: %s (电量%d%%)", d.Name, status, d.Battery)
|
|
default:
|
|
return fmt.Sprintf("%s: %s", d.Name, d.Status)
|
|
}
|
|
}
|