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

如何用Python获取Ninjutso Sora V2无线鼠标充电信息?

为什么pyusb访问Ninjutso Sora V2会触发[Errno 5],以及正确的pyusb实现方法

错误原因分析

1. HID报告格式未正确构造

HID设备通信依赖标准报告结构,通常包含1字节的报告ID(即使设备未显式使用,部分厂商仍要求填充0作为占位符)。hidapi会自动处理这个前置字节,而pyusb作为底层USB库,需要你手动构造完整的报告数据包。如果你的请求缺失报告ID或长度不符合设备要求,设备会直接返回IO错误。

2. 自定义Usage Page未匹配

Ninjutso Sora V2使用了0xFFA0这个自定义Usage Page,hidapitester通过指定该参数告知设备要调用对应功能集。pyusb直接操作端点时,没有关联这个Usage Page的上下文,设备无法识别请求所属的功能模块,因此拒绝响应。

3. 端点类型或方向错误

HID设备普遍使用中断端点(Interrupt Endpoint)进行数据交互,而非批量端点。如果你的pyusb代码误选了批量端点,或者用输出端点发送读取类请求,就会触发IO错误。

4. 设备隐性协议未满足

部分厂商会在HID报告中加入校验位、固定前缀/后缀等隐性规则,hidapi已经封装了这些细节,但pyusb要求你完全遵循设备的通信协议构造数据包,稍有偏差就会失败。


正确的pyusb实现步骤

1. 确认设备信息与端点

首先用lsusb(Linux)或设备管理器(Windows)获取Ninjutso Sora V2的VID/PID,再找到对应的HID中断端点(输出端点用于发送请求,输入端点用于接收响应)。

2. 完整代码实现

import usb.core
import usb.util

# 替换为你的Ninjutso Sora V2的VID和PID
VID = 0xXXXX
PID = 0xYYYY

# 定位设备
dev = usb.core.find(idVendor=VID, idProduct=PID)
if not dev:
    raise ValueError("未找到目标设备")

# 分离内核驱动(若已加载)
if dev.is_kernel_driver_active(0):
    dev.detach_kernel_driver(0)

# 声明HID接口
usb.util.claim_interface(dev, 0)

# 查找HID中断端点
out_ep = None
in_ep = None
for cfg in dev:
    for intf in cfg:
        if intf.bInterfaceClass == 3:  # 筛选HID类接口
            for ep in intf:
                ep_dir = usb.util.endpoint_direction(ep.bEndpointAddress)
                if ep_dir == usb.util.ENDPOINT_OUT:
                    out_ep = ep
                elif ep_dir == usb.util.ENDPOINT_IN:
                    in_ep = ep
if not out_ep or not in_ep:
    raise ValueError("未找到HID中断端点")

# 构造HID报告:参考你提取的JS代码中的请求数据
# 示例:若JS中用sendReport(0x01, [0x02, 0x03]),则报告数据为b'\x01\x02\x03'
# 注意:需匹配设备报告描述符规定的长度,不足补0
report_data = b'\x01' + b'\x02\x03\x04' + b'\x00'*59  # 假设报告长度为64字节

try:
    # 发送中断请求
    dev.write(out_ep.bEndpointAddress, report_data, timeout=1000)
    # 读取响应(长度需匹配设备返回的报告长度)
    response = dev.read(in_ep.bEndpointAddress, 64, timeout=1000)
    print("充电信息响应:", response)
except usb.core.USBError as e:
    print(f"USB错误:{e}")
finally:
    # 释放资源
    usb.util.release_interface(dev, 0)
    if dev.is_kernel_driver_active(0):
        dev.attach_kernel_driver(0)

3. 关键注意事项

  • 匹配报告ID与格式:从你提取的JS代码中,找到reportId和data字段,确保pyusb的report_data包含正确的报告ID,且总长度符合设备报告描述符的要求。
  • 验证端点类型:通过lsusb -v查看设备的端点信息,确认选中的是中断端点(bEndpointAddress的第7位为1表示输入,0表示输出,bmAttributes的第0-1位为0x03表示中断传输)。
  • 权限配置:Linux下需添加udev规则赋予普通用户USB访问权限,Windows下需用Zadig等工具为设备安装libusb驱动。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 04:32:19