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

如何通过Go-CoAP获取飞利浦AC3033净化器状态无需物理操作?

飞利浦AC3033空气净化器COAP协议获取状态问题

我希望通过COAP协议连接飞利浦AC3033空气净化器,获取其当前统计数据/状态。

成功获取设备信息的Go代码

package main

import (
    "context"
    "log"
    "time"

    "github.com/plgd-dev/go-coap/v3/udp"
)

func main() {
    co, err := udp.Dial("192.168.0.12:5683")
    if err != nil {
        log.Fatalf("Error dialing: %v", err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 2 * time.Second)
    defer cancel()

    resp, err := co.Get(ctx, "/sys/dev/info")
    if err != nil {
        log.Fatalf("Error sending request: %v", err)
    }
    log.Printf("Response payload: %+v", resp)
}

返回的设备信息:

{
    "product_id": "<id>",
    "device_id": "<id>",
    "name": "Living Room",
    "type": "AC3033",
    "modelid":"AC3033/14",
    "swversion":"Ms3411",
    "option":"1"
}

获取状态失败的尝试

尝试调用/sys/dev/status接口获取统计数据,代码如下:

package main

import (
    "context"
    "log"
    "time"

    "github.com/plgd-dev/go-coap/v3/udp"
)

func main() {
    co, err := udp.Dial("192.168.0.12:5683")
    if err != nil {
        log.Fatalf("Error dialing: %v", err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), 2 * time.Second)
    defer cancel()

    resp, err := co.Get(ctx, "/sys/dev/status")
    if err != nil {
        log.Fatalf("Error sending request: %v", err)
    }
    log.Printf("Response payload: %+v", resp)
}

执行后挂起2秒报错:

2024/12/07 22:20:36 Error sending request: cannot write request: cannot write request: context deadline exceeded

使用aioairctrl工具同样出现问题:

pip install aioairctrl
aioairctrl --host 192.168.0.12 status --json

命令会挂起,直到按下设备上的按钮才会输出当前统计数据/状态。

问题

是否有无需物理操作设备即可获取其当前统计数据的方法?


解决方案

飞利浦这类设备的COAP接口默认需要设备处于本地控制授权状态,物理按键操作实际是触发了临时授权窗口。要绕过物理操作,有以下几种可行方式:

  • 开启永久本地控制权限
    部分飞利浦空气净化器支持在设备WiFi设置菜单中开启"允许本地API访问"类选项,开启后无需每次按键授权,可直接通过COAP接口获取状态。

  • 携带配对授权密钥请求
    设备首次配对WiFi时会生成本地访问授权密钥,可通过飞利浦官方APP调试模式或设备WiFi配置信息导出。在COAP请求中携带该密钥作为认证参数即可:

    package main
    
    import (
        "context"
        "io"
        "log"
        "time"
    
        "github.com/plgd-dev/go-coap/v3/message"
        "github.com/plgd-dev/go-coap/v3/udp"
    )
    
    func main() {
        co, err := udp.Dial("192.168.0.12:5683")
        if err != nil {
            log.Fatalf("Error dialing: %v", err)
        }
        defer co.Close()
    
        ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
        defer cancel()
    
        // 创建请求并添加授权参数
        req, err := co.NewGetRequest(ctx, "/sys/dev/status")
        if err != nil {
            log.Fatalf("Failed to create request: %v", err)
        }
        // 替换<你的授权密钥>为实际密钥
        req.AddOption(message.URIQuery, "auth=<你的授权密钥>")
        req.SetOption(message.ContentFormat, message.JSON)
    
        resp, err := co.Do(req)
        if err != nil {
            log.Fatalf("Error sending request: %v", err)
        }
        defer resp.Body.Close()
    
        data, err := io.ReadAll(resp.Body)
        if err != nil {
            log.Fatalf("Error reading response: %v", err)
        }
        log.Printf("Response payload: %s", string(data))
    }
    
  • 订阅设备状态推送
    飞利浦设备支持COAP的Observe机制,发起观察请求订阅/sys/dev/status后,设备会主动推送状态更新,无需主动查询(部分设备仅首次订阅时需一次授权):

    package main
    
    import (
        "context"
        "io"
        "log"
    
        "github.com/plgd-dev/go-coap/v3/udp"
    )
    
    func main() {
        co, err := udp.Dial("192.168.0.12:5683")
        if err != nil {
            log.Fatalf("Error dialing: %v", err)
        }
        defer co.Close()
    
        ctx, cancel := context.WithCancel(context.Background())
        defer cancel()
    
        // 发起观察请求,接收状态推送
        err = co.Observe(ctx, "/sys/dev/status", func(req *udp.Request) {
            if req.Body != nil {
                data, _ := io.ReadAll(req.Body)
                log.Printf("Received status update: %s", string(data))
            }
        })
        if err != nil {
            log.Fatalf("Error observing: %v", err)
        }
    
        // 保持程序运行以持续接收推送
        select {}
    }
    
  • 模拟授权广播包(进阶)
    抓包分析物理按键按下时设备发送的本地广播信号,模拟该广播包触发临时授权窗口,之后再发起COAP请求。此方式需抓包分析设备协议,实现难度较高。


内容的提问来源于stack exchange,提问作者yellowhat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 15:49:52