Files
McpServerCSharp/AspNetCoreMcpServer/Tools/IotDeviceTools.cs
2025-11-13 16:07:34 +08:00

526 lines
17 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using ModelContextProtocol;
using ModelContextProtocol.Server;
using System.ComponentModel;
using System.Globalization;
using System.Text.Json;
namespace AspNetCoreMcpServer.Tools;
[McpServerToolType]
public sealed class IotDeviceTools
{
// 模拟设备状态存储
private static readonly Dictionary<string, DeviceState> _deviceStates = new();
public IotDeviceTools()
{
// 初始化一些默认设备
InitializeDefaultDevices();
}
private void InitializeDefaultDevices()
{
_deviceStates["living_room_light"] = new DeviceState
{
Id = "living_room_light",
Name = "客厅灯",
Type = "light",
IsOn = false,
Brightness = 100,
Temperature = 4000
};
_deviceStates["bedroom_curtain"] = new DeviceState
{
Id = "bedroom_curtain",
Name = "卧室窗帘",
Type = "curtain",
IsOn = false,
Position = 0
};
_deviceStates["living_room_ac"] = new DeviceState
{
Id = "living_room_ac",
Name = "客厅空调",
Type = "air_conditioner",
IsOn = false,
Temperature = 26,
Mode = "cool",
FanSpeed = "medium"
};
}
// ==================== 灯光控制 ====================
[McpServerTool, Description("控制灯光的开关状态")]
[McpMeta("category", "iot")]
[McpMeta("device", "light")]
public async Task<string> ControlLight(
[Description("设备ID例如: living_room_light, bedroom_light")] string deviceId,
[Description("开关状态: on 或 off")] string action)
{
await Task.Delay(100); // 模拟网络延迟
if (!_deviceStates.ContainsKey(deviceId))
{
return $"错误: 找不到设备 {deviceId}";
}
var device = _deviceStates[deviceId];
if (device.Type != "light")
{
return $"错误: {deviceId} 不是灯光设备";
}
bool turnOn = action.ToLower() == "on";
device.IsOn = turnOn;
return $"""
设备控制成功
设备: {device.Name} ({deviceId})
状态: {(turnOn ? "" : "")}
: {device.Brightness}%
: {device.Temperature}K
""";
}
[McpServerTool, Description("调节灯光亮度")]
[McpMeta("category", "iot")]
[McpMeta("device", "light")]
public async Task<string> SetLightBrightness(
[Description("设备ID")] string deviceId,
[Description("亮度值 (0-100)")] int brightness)
{
await Task.Delay(100);
if (!_deviceStates.ContainsKey(deviceId))
{
return $"错误: 找不到设备 {deviceId}";
}
var device = _deviceStates[deviceId];
if (device.Type != "light")
{
return $"错误: {deviceId} 不是灯光设备";
}
if (brightness < 0 || brightness > 100)
{
return "错误: 亮度值必须在 0-100 之间";
}
device.Brightness = brightness;
if (brightness > 0 && !device.IsOn)
{
device.IsOn = true;
}
return $"""
亮度调节成功
设备: {device.Name}
当前亮度: {brightness}%
状态: {(device.IsOn ? "" : "")}
""";
}
[McpServerTool, Description("调节灯光色温")]
[McpMeta("category", "iot")]
[McpMeta("device", "light")]
public async Task<string> SetLightTemperature(
[Description("设备ID")] string deviceId,
[Description("色温值 (2700-6500K)")] int temperature)
{
await Task.Delay(100);
if (!_deviceStates.ContainsKey(deviceId))
{
return $"错误: 找不到设备 {deviceId}";
}
var device = _deviceStates[deviceId];
if (device.Type != "light")
{
return $"错误: {deviceId} 不是灯光设备";
}
if (temperature < 2700 || temperature > 6500)
{
return "错误: 色温值必须在 2700-6500K 之间";
}
device.Temperature = temperature;
string tempDesc = temperature < 3500 ? "暖光" : temperature < 5000 ? "自然光" : "冷光";
return $"""
色温调节成功
设备: {device.Name}
当前色温: {temperature}K ({tempDesc})
亮度: {device.Brightness}%
""";
}
// ==================== 窗帘控制 ====================
[McpServerTool, Description("控制窗帘的开关")]
[McpMeta("category", "iot")]
[McpMeta("device", "curtain")]
public async Task<string> ControlCurtain(
[Description("设备ID例如: bedroom_curtain")] string deviceId,
[Description("操作: open(打开), close(关闭), stop(停止)")] string action)
{
await Task.Delay(200); // 模拟窗帘运行时间
if (!_deviceStates.ContainsKey(deviceId))
{
return $"错误: 找不到设备 {deviceId}";
}
var device = _deviceStates[deviceId];
if (device.Type != "curtain")
{
return $"错误: {deviceId} 不是窗帘设备";
}
string result = action.ToLower() switch
{
"open" => HandleCurtainOpen(device),
"close" => HandleCurtainClose(device),
"stop" => HandleCurtainStop(device),
_ => "错误: 无效的操作,请使用 open, close 或 stop"
};
return result;
}
[McpServerTool, Description("设置窗帘打开的位置")]
[McpMeta("category", "iot")]
[McpMeta("device", "curtain")]
public async Task<string> SetCurtainPosition(
[Description("设备ID")] string deviceId,
[Description("位置百分比 (0-100)0表示完全关闭100表示完全打开")] int position)
{
await Task.Delay(150);
if (!_deviceStates.ContainsKey(deviceId))
{
return $"错误: 找不到设备 {deviceId}";
}
var device = _deviceStates[deviceId];
if (device.Type != "curtain")
{
return $"错误: {deviceId} 不是窗帘设备";
}
if (position < 0 || position > 100)
{
return "错误: 位置值必须在 0-100 之间";
}
device.Position = position;
device.IsOn = position > 0;
return $"""
窗帘位置调节成功
设备: {device.Name}
当前位置: {position}%
状态: {(position == 0 ? "" : position == 100 ? "" : "")}
""";
}
// ==================== 空调控制 ====================
[McpServerTool, Description("控制空调的开关")]
[McpMeta("category", "iot")]
[McpMeta("device", "air_conditioner")]
public async Task<string> ControlAirConditioner(
[Description("设备ID例如: living_room_ac")] string deviceId,
[Description("开关状态: on 或 off")] string action)
{
await Task.Delay(100);
if (!_deviceStates.ContainsKey(deviceId))
{
return $"错误: 找不到设备 {deviceId}";
}
var device = _deviceStates[deviceId];
if (device.Type != "air_conditioner")
{
return $"错误: {deviceId} 不是空调设备";
}
bool turnOn = action.ToLower() == "on";
device.IsOn = turnOn;
return $"""
空调控制成功
设备: {device.Name}
状态: {(turnOn ? "" : "")}
{(turnOn ? $"温度: {device.Temperature}°C\n模式: {GetModeDescription(device.Mode)}\n风速: {GetFanSpeedDescription(device.FanSpeed)}" : "")}
""";
}
[McpServerTool, Description("设置空调温度")]
[McpMeta("category", "iot")]
[McpMeta("device", "air_conditioner")]
public async Task<string> SetAirConditionerTemperature(
[Description("设备ID")] string deviceId,
[Description("目标温度 (16-30°C)")] int temperature)
{
await Task.Delay(100);
if (!_deviceStates.ContainsKey(deviceId))
{
return $"错误: 找不到设备 {deviceId}";
}
var device = _deviceStates[deviceId];
if (device.Type != "air_conditioner")
{
return $"错误: {deviceId} 不是空调设备";
}
if (temperature < 16 || temperature > 30)
{
return "错误: 温度必须在 16-30°C 之间";
}
device.Temperature = temperature;
if (!device.IsOn)
{
device.IsOn = true;
}
return $"""
空调温度设置成功
设备: {device.Name}
目标温度: {temperature}°C
当前模式: {GetModeDescription(device.Mode)}
风速: {GetFanSpeedDescription(device.FanSpeed)}
""";
}
[McpServerTool, Description("设置空调模式")]
[McpMeta("category", "iot")]
[McpMeta("device", "air_conditioner")]
public async Task<string> SetAirConditionerMode(
[Description("设备ID")] string deviceId,
[Description("模式: cool(制冷), heat(制热), fan(送风), dry(除湿), auto(自动)")] string mode)
{
await Task.Delay(100);
if (!_deviceStates.ContainsKey(deviceId))
{
return $"错误: 找不到设备 {deviceId}";
}
var device = _deviceStates[deviceId];
if (device.Type != "air_conditioner")
{
return $"错误: {deviceId} 不是空调设备";
}
var validModes = new[] { "cool", "heat", "fan", "dry", "auto" };
if (!validModes.Contains(mode.ToLower()))
{
return $"错误: 无效的模式。有效模式: {string.Join(", ", validModes)}";
}
device.Mode = mode.ToLower();
return $"""
空调模式设置成功
设备: {device.Name}
当前模式: {GetModeDescription(device.Mode)}
温度: {device.Temperature}°C
风速: {GetFanSpeedDescription(device.FanSpeed)}
""";
}
[McpServerTool, Description("设置空调风速")]
[McpMeta("category", "iot")]
[McpMeta("device", "air_conditioner")]
public async Task<string> SetAirConditionerFanSpeed(
[Description("设备ID")] string deviceId,
[Description("风速: low(低), medium(中), high(高), auto(自动)")] string fanSpeed)
{
await Task.Delay(100);
if (!_deviceStates.ContainsKey(deviceId))
{
return $"错误: 找不到设备 {deviceId}";
}
var device = _deviceStates[deviceId];
if (device.Type != "air_conditioner")
{
return $"错误: {deviceId} 不是空调设备";
}
var validSpeeds = new[] { "low", "medium", "high", "auto" };
if (!validSpeeds.Contains(fanSpeed.ToLower()))
{
return $"错误: 无效的风速。有效风速: {string.Join(", ", validSpeeds)}";
}
device.FanSpeed = fanSpeed.ToLower();
return $"""
空调风速设置成功
设备: {device.Name}
当前风速: {GetFanSpeedDescription(device.FanSpeed)}
模式: {GetModeDescription(device.Mode)}
温度: {device.Temperature}°C
""";
}
// ==================== 通用查询 ====================
[McpServerTool, Description("获取所有IoT设备的状态")]
[McpMeta("category", "iot")]
[McpMeta("device", "all")]
public async Task<string> GetAllDevicesStatus()
{
await Task.Delay(50);
var statusList = _deviceStates.Values.Select(device =>
{
string status = device.Type switch
{
"light" => $"开关: {(device.IsOn ? "" : "")}, 亮度: {device.Brightness}%, 色温: {device.Temperature}K",
"curtain" => $"位置: {device.Position}%, 状态: {(device.Position == 0 ? "" : device.Position == 100 ? "" : "")}",
"air_conditioner" => $"开关: {(device.IsOn ? "" : "")}, 温度: {device.Temperature}°C, 模式: {GetModeDescription(device.Mode)}, 风速: {GetFanSpeedDescription(device.FanSpeed)}",
_ => "未知设备类型"
};
return $"""
[{device.Type.ToUpper()}] {device.Name} ({device.Id})
{status}
""";
});
return $"当前设备总数: {_deviceStates.Count}\n\n" + string.Join("\n---\n", statusList);
}
[McpServerTool, Description("获取指定设备的详细状态")]
[McpMeta("category", "iot")]
[McpMeta("device", "all")]
public async Task<string> GetDeviceStatus(
[Description("设备ID")] string deviceId)
{
await Task.Delay(50);
if (!_deviceStates.ContainsKey(deviceId))
{
return $"错误: 找不到设备 {deviceId}\n\n可用设备: {string.Join(", ", _deviceStates.Keys)}";
}
var device = _deviceStates[deviceId];
string details = device.Type switch
{
"light" => $"""
开关状态: {(device.IsOn ? "" : "")}
: {device.Brightness}%
: {device.Temperature}K ({(device.Temperature < 3500 ? "暖光" : device.Temperature < 5000 ? "自然光" : "冷光")})
""",
"curtain" => $"""
位置: {device.Position}%
状态: {(device.Position == 0 ? "" : device.Position == 100 ? "" : "")}
""",
"air_conditioner" => $"""
开关状态: {(device.IsOn ? "" : "")}
: {device.Temperature}°C
: {GetModeDescription(device.Mode)}
: {GetFanSpeedDescription(device.FanSpeed)}
""",
_ => "未知设备类型"
};
return $"""
设备信息
名称: {device.Name}
ID: {device.Id}
类型: {device.Type}
{details}
""";
}
// ==================== 辅助方法 ====================
private string HandleCurtainOpen(DeviceState device)
{
device.Position = 100;
device.IsOn = true;
return $"""
窗帘正在打开...
设备: {device.Name}
目标位置: 100% (完全打开)
预计时间: 5秒
""";
}
private string HandleCurtainClose(DeviceState device)
{
device.Position = 0;
device.IsOn = false;
return $"""
窗帘正在关闭...
设备: {device.Name}
目标位置: 0% (完全关闭)
预计时间: 5秒
""";
}
private string HandleCurtainStop(DeviceState device)
{
return $"""
窗帘已停止
设备: {device.Name}
当前位置: {device.Position}%
""";
}
private static string GetModeDescription(string? mode) => mode switch
{
"cool" => "制冷",
"heat" => "制热",
"fan" => "送风",
"dry" => "除湿",
"auto" => "自动",
_ => "未知"
};
private static string GetFanSpeedDescription(string? speed) => speed switch
{
"low" => "低速",
"medium" => "中速",
"high" => "高速",
"auto" => "自动",
_ => "未知"
};
}
// 设备状态数据模型
internal class DeviceState
{
public string Id { get; set; } = "";
public string Name { get; set; } = "";
public string Type { get; set; } = "";
public bool IsOn { get; set; }
// 灯光属性
public int Brightness { get; set; }
public int Temperature { get; set; }
// 窗帘属性
public int Position { get; set; }
// 空调属性
public string? Mode { get; set; }
public string? FanSpeed { get; set; }
}