You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 00:35:02