调用FritzBox API的getdevicelistinfos返回空设备列表求助
问题描述
我正尝试通过C#代码调用FritzBox API获取家庭网络中的所有设备。目前可正常登录并获取后续请求所需的SID,但调用getdevicelistinfos方法时,仅返回:
<devicelist version="1" fwversion="7.57"/>
请求URL示例:http://fritz.box/webservices/homeautoswitch.lua?0=0&sid=secret&switchcmd=getdevicelistinfos
我原本理解该端点会返回所有设备,但实际并非如此,已尝试修改请求URL,相关C#代码如下:
static async Task Main(string[] args) { try { var sessionId = await GetSessionId(); var devices = await GetDeviceInfo(sessionId, ""); } catch (Exception ex) { } } private static async Task<string> GetSessionId() { using (var client = new HttpClient() { BaseAddress = new Uri(FritzBoxUrl)}) { var response = await client.GetStringAsync("/login_sid.lua"); var xml = XDocument.Parse(response); var sid = xml.Root.Element("SID").Value; if (sid != "0000000000000000") { return sid; } var challenge = xml.Root.Element("Challenge").Value; fritzUserName = xml.Root.Element("Users")?.Element("User").Value; var responseHash = CalculateMD5(challenge + "-" + Password); var content = new StringContent($"response={challenge}-{responseHash}&username={fritzUserName}", Encoding.UTF8, "application/x-www-form-urlencoded"); var loginResponse = await client.PostAsync("/login_sid.lua", content); var loginResponseContent = await loginResponse.Content.ReadAsStringAsync(); var loginXml = XDocument.Parse(loginResponseContent); var loginSid = loginXml.Root.Element("SID").Value; if (loginSid == "0000000000000000") { throw new Exception(); } return loginSid; } } private static async Task<string> ExecuteCommand(string sid, string command, string ain, string path) { path += "/webservices/homeautoswitch.lua?0=0"; if (!string.IsNullOrEmpty(sid)) path += "&sid=" + sid; if (!string.IsNullOrEmpty(command)) path += "&switchcmd=" + command; if (!string.IsNullOrEmpty(ain)) path += "&ain" + ain; return await HttpRequest(path, new HttpRequestMessage(), ""); } public static async Task<string> HttpRequest(string path, HttpRequestMessage req, string options) { req.RequestUri = new Uri(FritzBoxUrl + path); var client = new HttpClient(); HttpResponseMessage response = await client.SendAsync(req); string body = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode || response.StatusCode == System.Net.HttpStatusCode.Redirect || body.Contains("action=.?login.lua")) { throw new HttpRequestException($"HTTP request failed: {response.StatusCode}"); } return body.Trim(); } private static async Task<string> GetDeviceInfo(string sessionId,string options) => await ExecuteCommand(sessionId, "getdevicelistinfos",null,options);
问题排查与解决方法
1. API端点使用错误
homeautoswitch.lua仅用于智能家居设备(开关、插座、温控器等),如果要获取所有网络设备(电脑、手机、IoT设备等),需要调用hosts.lua的gethosts命令,而非homeautoswitch.lua的getdevicelistinfos。
- 若要获取智能家居设备,保留原端点,确保你的FritzBox已关联智能家居设备;
- 若要获取网络设备,使用以下请求格式:
http://fritz.box/hosts.lua?sid=你的SID&cmd=gethosts
2. 权限不足
当前登录用户可能没有访问设备列表的权限,需在FritzBox后台配置:
- 进入「系统 > 权限」菜单;
- 确保当前用户拥有「访问智能家居」或「查看网络设备」的对应权限(根据目标设备类型选择)。
3. 代码URL拼接bug
检查ExecuteCommand方法中的参数拼接逻辑:
- 拼接
ain参数时缺少=号,会导致参数无效,修正为:if (!string.IsNullOrEmpty(ain)) path += "&ain=" + ain; - 冗余的
0=0参数可移除,不影响功能但会增加URL复杂度。
4. 固件兼容性验证
你的固件版本为7.57,可登录FritzBox后台「帮助 > API帮助」页面,查看getdevicelistinfos的官方说明,确认是否存在参数变更或端点调整。
修正后的代码示例
获取智能家居设备的修正代码
private static async Task<string> ExecuteCommand(string sid, string command, string ain, string path) { // 避免空path导致的重复斜杠问题 var basePath = string.IsNullOrEmpty(path) ? "/webservices/homeautoswitch.lua" : path + "/webservices/homeautoswitch.lua"; var queryParams = new List<string>(); if (!string.IsNullOrEmpty(sid)) queryParams.Add($"sid={sid}"); if (!string.IsNullOrEmpty(command)) queryParams.Add($"switchcmd={command}"); if (!string.IsNullOrEmpty(ain)) queryParams.Add($"ain={ain}"); var fullPath = basePath + (queryParams.Any() ? "?" + string.Join("&", queryParams) : ""); return await HttpRequest(fullPath, new HttpRequestMessage(), ""); }
获取网络设备的新增方法
private static async Task<string> GetNetworkDevices(string sessionId) { var path = $"/hosts.lua?sid={sessionId}&cmd=gethosts"; return await HttpRequest(path, new HttpRequestMessage(), ""); }
调用示例
static async Task Main(string[] args) { try { var sessionId = await GetSessionId(); // 获取智能家居设备 var smartDevices = await GetDeviceInfo(sessionId, ""); // 获取网络设备 var networkDevices = await GetNetworkDevices(sessionId); } catch (Exception ex) { Console.WriteLine(ex.Message); } }
内容的提问来源于stack exchange,提问作者SoldatXwing
相关产品推荐
相关产品推荐

